Merge "BT: Aptx-Adaptive AIDL changes"
diff --git a/audio/7.1/Android.bp b/audio/7.1/Android.bp
new file mode 100644
index 0000000..52980e2
--- /dev/null
+++ b/audio/7.1/Android.bp
@@ -0,0 +1,32 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+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"],
+}
+
+hidl_interface {
+    name: "android.hardware.audio@7.1",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "IDevice.hal",
+        "IDevicesFactory.hal",
+        "IPrimaryDevice.hal",
+        "IStreamIn.hal",
+        "IStreamOut.hal",
+        "IStreamOutLatencyModeCallback.hal",
+    ],
+    interfaces: [
+        "android.hardware.audio@7.0",
+        "android.hardware.audio.common@7.0",
+        "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
+    ],
+    gen_java: false,
+    gen_java_constants: false,
+}
diff --git a/audio/7.1/IDevice.hal b/audio/7.1/IDevice.hal
new file mode 100644
index 0000000..373d17f
--- /dev/null
+++ b/audio/7.1/IDevice.hal
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+import android.hardware.audio.common@7.0;
+import @7.0::AudioInOutFlag;
+import @7.0::IDevice;
+import @7.0::Result;
+import IStreamIn;
+import IStreamOut;
+
+interface IDevice extends @7.0::IDevice {
+    /**
+     * This method creates and opens the audio hardware output stream.
+     * If the stream can not be opened with the proposed audio config,
+     * HAL must provide suggested values for the audio config.
+     *
+     * Note: INVALID_ARGUMENTS is returned both in the case when the
+     * HAL can not use the provided config and in the case when
+     * the value of any argument is invalid. In the latter case the
+     * HAL must provide a default initialized suggested config.
+     *
+     * @param ioHandle handle assigned by AudioFlinger.
+     * @param device device type and (if needed) address.
+     * @param config stream configuration.
+     * @param flags additional flags.
+     * @param sourceMetadata Description of the audio that will be played.
+                             May be used by implementations to configure hardware effects.
+     * @return retval operation completion status.
+     * @return outStream created output stream.
+     * @return suggestedConfig in the case of rejection of the proposed config,
+     *                         a config suggested by the HAL.
+     */
+    openOutputStream_7_1(
+            AudioIoHandle ioHandle,
+            DeviceAddress device,
+            AudioConfig config,
+            vec<AudioInOutFlag> flags,
+            SourceMetadata sourceMetadata) generates (
+                    Result retval,
+                    IStreamOut outStream,
+                    AudioConfig suggestedConfig);
+
+    /**
+     * This method creates and opens the audio hardware input stream.
+     * If the stream can not be opened with the proposed audio config,
+     * HAL must provide suggested values for the audio config.
+     *
+     * Note: INVALID_ARGUMENTS is returned both in the case when the
+     * HAL can not use the provided config and in the case when
+     * the value of any argument is invalid. In the latter case the
+     * HAL must provide a default initialized suggested config.
+     *
+     * @param ioHandle handle assigned by AudioFlinger.
+     * @param device device type and (if needed) address.
+     * @param config stream configuration.
+     * @param flags additional flags.
+     * @param sinkMetadata Description of the audio that is suggested by the client.
+     *                     May be used by implementations to configure processing effects.
+     * @return retval operation completion status.
+     * @return inStream in case of success, created input stream.
+     * @return suggestedConfig in the case of rejection of the proposed config,
+     *                         a config suggested by the HAL.
+     */
+    openInputStream_7_1(
+            AudioIoHandle ioHandle,
+            DeviceAddress device,
+            AudioConfig config,
+            vec<AudioInOutFlag> flags,
+            SinkMetadata sinkMetadata) generates (
+                    Result retval,
+                    IStreamIn inStream,
+                    AudioConfig suggestedConfig);
+};
diff --git a/audio/7.1/IDevicesFactory.hal b/audio/7.1/IDevicesFactory.hal
new file mode 100644
index 0000000..7669614
--- /dev/null
+++ b/audio/7.1/IDevicesFactory.hal
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+import @7.0::IDevicesFactory;
+import @7.0::Result;
+import IDevice;
+import IPrimaryDevice;
+
+/**
+ * This factory allows a HAL implementation to be split in multiple independent
+ * devices (called module in the pre-treble API). Note that this division is
+ * arbitrary and implementation are free to only have a Primary. The framework
+ * will query the devices according to audio_policy_configuration.xml
+ *
+ * Each device name is arbitrary, provided by the vendor's audio_policy_configuration.xml
+ * and only used to identify a device in this factory.
+ * The framework must not interpret the name, treating it as a vendor opaque data
+ * with the following exception:
+ * - the "r_submix" device that must be present to support policyMixes (Eg: Android projected).
+ *   Note that this Device is included by default in a build derived from AOSP.
+ */
+interface IDevicesFactory extends @7.0::IDevicesFactory {
+
+    /**
+     * Opens an audio device. To close the device, it is necessary to call
+     * 'close' method on the returned device object.
+     *
+     * Important note: due to rules of HIDL, @7.1::IPrimaryDevice extends
+     * @7.0::IPrimaryDevice, rather than @7.1::IDevice. Thus the returned
+     * IDevice interface can not be up-casted to @7.1::IPrimaryDevice for the
+     * primary device. The client needs to use IPrimaryDevice instead of this
+     * method if it needs full functionality of the IPrimaryDevice interface.
+     *
+     * @param device device name.
+     * @return retval operation completion status. Returns INVALID_ARGUMENTS
+     *         if there is no corresponding hardware module found,
+     *         NOT_INITIALIZED if an error occurred while opening the hardware
+     *         module.
+     * @return result the interface for the created device.
+     */
+    openDevice_7_1(string device) generates (Result retval, IDevice result);
+
+    /**
+     * Opens the Primary audio device that must be present.
+     * This function is not optional and must return successfully the primary device.
+     *
+     * This device must have the name "primary".
+     *
+     * The telephony stack uses this device to control the audio during a voice call.
+     *
+     * @return retval operation completion status. Must be SUCCESS.
+     *         For debugging, return INVALID_ARGUMENTS if there is no corresponding
+     *         hardware module found, NOT_INITIALIZED if an error occurred
+     *         while opening the hardware module.
+     * @return result the interface for the created device.
+     */
+    openPrimaryDevice_7_1() generates (Result retval, IPrimaryDevice result);
+};
diff --git a/audio/7.1/IPrimaryDevice.hal b/audio/7.1/IPrimaryDevice.hal
new file mode 100644
index 0000000..1659671
--- /dev/null
+++ b/audio/7.1/IPrimaryDevice.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+import android.hardware.audio.common@7.0;
+import @7.0::IPrimaryDevice;
+import IDevice;
+
+interface IPrimaryDevice extends @7.0::IPrimaryDevice {
+    /**
+     * Retrieve the generic @7.1::IDevice interface.
+     *
+     * Since @7.1::IPrimaryDevice extends @7.0::IPrimaryDevice, the interface
+     * reference can not be downcasted to @7.1::IDevice using standard methods.
+     * For this reason a dedicated interface method is provided.
+     *
+     * @return result the generic part of the interface.
+     */
+    getDevice() generates (IDevice result);
+};
diff --git a/audio/7.1/IStreamIn.hal b/audio/7.1/IStreamIn.hal
new file mode 100644
index 0000000..abebe6a
--- /dev/null
+++ b/audio/7.1/IStreamIn.hal
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+import @7.0::IStreamIn;
+
+interface IStreamIn extends @7.0::IStreamIn {
+};
diff --git a/audio/7.1/IStreamOut.hal b/audio/7.1/IStreamOut.hal
new file mode 100644
index 0000000..b2013cf
--- /dev/null
+++ b/audio/7.1/IStreamOut.hal
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+import @7.0::Result;
+import @7.0::IStreamOut;
+
+import IStreamOutLatencyModeCallback;
+
+interface IStreamOut extends @7.0::IStreamOut {
+    /**
+     * Indicates the requested latency mode for this output stream.
+     *
+     * The requested mode can be one of the modes returned by
+     * getRecommendedLatencyModes() API.
+     *
+     * Optional method.
+     * Mandated only on specific spatial audio streams indicated by
+     * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+     *
+     * @return retval operation completion status.
+     */
+    setLatencyMode(LatencyMode mode) generates (Result retval);
+
+    /**
+     * Indicates which latency modes are currently supported on this output stream.
+     * If the transport protocol (e.g Bluetooth A2DP) used by this output stream to reach
+     * the output device supports variable latency modes, the HAL indicates which
+     * modes are currently supported.
+     * The framework can then call setLatencyMode() with one of the supported modes to select
+     * the desired operation mode.
+     *
+     * Optional method.
+     * Mandated only on specific spatial audio streams indicated by
+     * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+     *
+     * @return retval operation completion status.
+     * @return modes currrently supported latency modes.
+     */
+    getRecommendedLatencyModes() generates (Result retval, vec<LatencyMode> modes);
+
+    /**
+     * Set the callback interface for notifying changes in supported latency modes.
+     *
+     * Calling this method with a null pointer will result in releasing
+     * the callback.
+     *
+     * Optional method.
+     * Mandated only on specific spatial audio streams indicated by
+     * AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed to a BT classic sink.
+     *
+     * @return retval operation completion status.
+     */
+    setLatencyModeCallback(IStreamOutLatencyModeCallback callback) generates (Result retval);
+};
diff --git a/audio/7.1/IStreamOutLatencyModeCallback.hal b/audio/7.1/IStreamOutLatencyModeCallback.hal
new file mode 100644
index 0000000..45b453f
--- /dev/null
+++ b/audio/7.1/IStreamOutLatencyModeCallback.hal
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+/**
+ * Callback interface for output stream variable latency mode feature.
+ */
+interface IStreamOutLatencyModeCallback {
+    /**
+     * Called with the new list of supported latency modes when a change occurs.
+     */
+    oneway onRecommendedLatencyModeChanged(vec<LatencyMode> modes);
+};
diff --git a/audio/7.1/config/Android.bp b/audio/7.1/config/Android.bp
new file mode 100644
index 0000000..70c8fd4
--- /dev/null
+++ b/audio/7.1/config/Android.bp
@@ -0,0 +1,31 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+    name: "audio_policy_configuration_V7_1",
+    srcs: ["audio_policy_configuration.xsd"],
+    package_name: "android.audio.policy.configuration.V7_1",
+    nullability: true,
+}
+
+xsd_config {
+    name: "audio_policy_configuration_V7_1_enums",
+    srcs: ["audio_policy_configuration.xsd"],
+    package_name: "android.audio.policy.configuration.V7_1",
+    nullability: true,
+    enums_only: true,
+}
+
+xsd_config {
+    name: "audio_policy_configuration_V7_1_parser",
+    srcs: ["audio_policy_configuration.xsd"],
+    package_name: "android.audio.policy.configuration.V7_1",
+    nullability: true,
+    parser_only: true,
+}
diff --git a/audio/7.1/config/api/current.txt b/audio/7.1/config/api/current.txt
new file mode 100644
index 0000000..0a0eb02
--- /dev/null
+++ b/audio/7.1/config/api/current.txt
@@ -0,0 +1,596 @@
+// Signature format: 2.0
+package android.audio.policy.configuration.V7_1 {
+
+  public class AttachedDevices {
+    ctor public AttachedDevices();
+    method @Nullable public java.util.List<java.lang.String> getItem();
+  }
+
+  public enum AudioChannelMask {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_6;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_MONO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_STEREO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_NONE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_13POINT_360RA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_22POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT6;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_TRI;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK;
+  }
+
+  public enum AudioContentType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public enum AudioDevice {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_AMBIENT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BACK_MIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_BUS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_IP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_LINE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_LOOPBACK;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_PROXY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_STUB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_TV_TUNER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_NONE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_BROADCAST;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_BUS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_FM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_IP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_LINE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_PROXY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_STUB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET;
+  }
+
+  public enum AudioEncapsulationType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
+  }
+
+  public enum AudioFormat {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADIF;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ELD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_ERLC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LATM_LC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_LTP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_MAIN;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_SSR;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AAC_XHE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AC3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AC4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_ALAC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_NB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_WB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_HD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_APTX_TWSP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_CELT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DRA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DSD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS_HD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_DTS_UHD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCNW;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_EVRCWB;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_E_AC3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_E_AC3_JOC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_FLAC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_IEC60958;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LC3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LDAC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LHDC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_LHDC_LL;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_1_0;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_2_0;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MAT_2_1;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MP2;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MP3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_OPUS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_16_BIT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_32_BIT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_8_BIT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_PCM_FLOAT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_QCELP;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_SBC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_VORBIS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_WMA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioFormat AUDIO_FORMAT_WMA_PRO;
+  }
+
+  public enum AudioGainMode {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_CHANNELS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_JOINT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioGainMode AUDIO_GAIN_MODE_RAMP;
+  }
+
+  public enum AudioInOutFlag {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SPATIALIZER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
+  }
+
+  public class AudioPolicyConfiguration {
+    ctor public AudioPolicyConfiguration();
+    method @Nullable public android.audio.policy.configuration.V7_1.GlobalConfiguration getGlobalConfiguration();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Modules> getModules();
+    method @Nullable public android.audio.policy.configuration.V7_1.SurroundSound getSurroundSound();
+    method @Nullable public android.audio.policy.configuration.V7_1.Version getVersion();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Volumes> getVolumes();
+    method public void setGlobalConfiguration(@Nullable android.audio.policy.configuration.V7_1.GlobalConfiguration);
+    method public void setSurroundSound(@Nullable android.audio.policy.configuration.V7_1.SurroundSound);
+    method public void setVersion(@Nullable android.audio.policy.configuration.V7_1.Version);
+  }
+
+  public enum AudioSource {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_CAMCORDER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_MIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_UNPROCESSED;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_UPLINK;
+  }
+
+  public enum AudioStreamType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ALARM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_DTMF;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_PATCH;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_REROUTING;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_RING;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_SYSTEM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_TTS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioStreamType AUDIO_STREAM_VOICE_CALL;
+  }
+
+  public enum AudioUsage {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ALARM;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_GAME;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public enum DeviceCategory {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.V7_1.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+  }
+
+  public class DevicePorts {
+    ctor public DevicePorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.DevicePorts.DevicePort> getDevicePort();
+  }
+
+  public static class DevicePorts.DevicePort {
+    ctor public DevicePorts.DevicePort();
+    method @Nullable public String getAddress();
+    method @Nullable public java.util.List<java.lang.String> getEncodedFormats();
+    method @Nullable public android.audio.policy.configuration.V7_1.Gains getGains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Profile> getProfile();
+    method @Nullable public android.audio.policy.configuration.V7_1.Role getRole();
+    method @Nullable public String getTagName();
+    method @Nullable public String getType();
+    method @Nullable public boolean get_default();
+    method public void setAddress(@Nullable String);
+    method public void setEncodedFormats(@Nullable java.util.List<java.lang.String>);
+    method public void setGains(@Nullable android.audio.policy.configuration.V7_1.Gains);
+    method public void setRole(@Nullable android.audio.policy.configuration.V7_1.Role);
+    method public void setTagName(@Nullable String);
+    method public void setType(@Nullable String);
+    method public void set_default(@Nullable boolean);
+  }
+
+  public enum EngineSuffix {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.EngineSuffix _default;
+    enum_constant public static final android.audio.policy.configuration.V7_1.EngineSuffix configurable;
+  }
+
+  public class Gains {
+    ctor public Gains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Gains.Gain> getGain();
+  }
+
+  public static class Gains.Gain {
+    ctor public Gains.Gain();
+    method @Nullable public android.audio.policy.configuration.V7_1.AudioChannelMask getChannel_mask();
+    method @Nullable public int getDefaultValueMB();
+    method @Nullable public int getMaxRampMs();
+    method @Nullable public int getMaxValueMB();
+    method @Nullable public int getMinRampMs();
+    method @Nullable public int getMinValueMB();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioGainMode> getMode();
+    method @Nullable public String getName();
+    method @Nullable public int getStepValueMB();
+    method @Nullable public boolean getUseForVolume();
+    method public void setChannel_mask(@Nullable android.audio.policy.configuration.V7_1.AudioChannelMask);
+    method public void setDefaultValueMB(@Nullable int);
+    method public void setMaxRampMs(@Nullable int);
+    method public void setMaxValueMB(@Nullable int);
+    method public void setMinRampMs(@Nullable int);
+    method public void setMinValueMB(@Nullable int);
+    method public void setMode(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioGainMode>);
+    method public void setName(@Nullable String);
+    method public void setStepValueMB(@Nullable int);
+    method public void setUseForVolume(@Nullable boolean);
+  }
+
+  public class GlobalConfiguration {
+    ctor public GlobalConfiguration();
+    method @Nullable public boolean getCall_screen_mode_supported();
+    method @Nullable public android.audio.policy.configuration.V7_1.EngineSuffix getEngine_library();
+    method @Nullable public boolean getSpeaker_drc_enabled();
+    method public void setCall_screen_mode_supported(@Nullable boolean);
+    method public void setEngine_library(@Nullable android.audio.policy.configuration.V7_1.EngineSuffix);
+    method public void setSpeaker_drc_enabled(@Nullable boolean);
+  }
+
+  public enum HalVersion {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.HalVersion _2_0;
+    enum_constant public static final android.audio.policy.configuration.V7_1.HalVersion _3_0;
+  }
+
+  public class MixPorts {
+    ctor public MixPorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.MixPorts.MixPort> getMixPort();
+  }
+
+  public static class MixPorts.MixPort {
+    ctor public MixPorts.MixPort();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioInOutFlag> getFlags();
+    method @Nullable public android.audio.policy.configuration.V7_1.Gains getGains();
+    method @Nullable public long getMaxActiveCount();
+    method @Nullable public long getMaxOpenCount();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioUsage> getPreferredUsage();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Profile> getProfile();
+    method @Nullable public android.audio.policy.configuration.V7_1.Role getRole();
+    method public void setFlags(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioInOutFlag>);
+    method public void setGains(@Nullable android.audio.policy.configuration.V7_1.Gains);
+    method public void setMaxActiveCount(@Nullable long);
+    method public void setMaxOpenCount(@Nullable long);
+    method public void setName(@Nullable String);
+    method public void setPreferredUsage(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioUsage>);
+    method public void setRole(@Nullable android.audio.policy.configuration.V7_1.Role);
+  }
+
+  public enum MixType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.MixType mix;
+    enum_constant public static final android.audio.policy.configuration.V7_1.MixType mux;
+  }
+
+  public class Modules {
+    ctor public Modules();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Modules.Module> getModule();
+  }
+
+  public static class Modules.Module {
+    ctor public Modules.Module();
+    method @Nullable public android.audio.policy.configuration.V7_1.AttachedDevices getAttachedDevices();
+    method @Nullable public String getDefaultOutputDevice();
+    method @Nullable public android.audio.policy.configuration.V7_1.DevicePorts getDevicePorts();
+    method @Nullable public android.audio.policy.configuration.V7_1.HalVersion getHalVersion();
+    method @Nullable public android.audio.policy.configuration.V7_1.MixPorts getMixPorts();
+    method @Nullable public String getName();
+    method @Nullable public android.audio.policy.configuration.V7_1.Routes getRoutes();
+    method public void setAttachedDevices(@Nullable android.audio.policy.configuration.V7_1.AttachedDevices);
+    method public void setDefaultOutputDevice(@Nullable String);
+    method public void setDevicePorts(@Nullable android.audio.policy.configuration.V7_1.DevicePorts);
+    method public void setHalVersion(@Nullable android.audio.policy.configuration.V7_1.HalVersion);
+    method public void setMixPorts(@Nullable android.audio.policy.configuration.V7_1.MixPorts);
+    method public void setName(@Nullable String);
+    method public void setRoutes(@Nullable android.audio.policy.configuration.V7_1.Routes);
+  }
+
+  public class Profile {
+    ctor public Profile();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioChannelMask> getChannelMasks();
+    method @Nullable public android.audio.policy.configuration.V7_1.AudioEncapsulationType getEncapsulationType();
+    method @Nullable public String getFormat();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.math.BigInteger> getSamplingRates();
+    method public void setChannelMasks(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioChannelMask>);
+    method public void setEncapsulationType(@Nullable android.audio.policy.configuration.V7_1.AudioEncapsulationType);
+    method public void setFormat(@Nullable String);
+    method public void setName(@Nullable String);
+    method public void setSamplingRates(@Nullable java.util.List<java.math.BigInteger>);
+  }
+
+  public class Reference {
+    ctor public Reference();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method public void setName(@Nullable String);
+  }
+
+  public enum Role {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.Role sink;
+    enum_constant public static final android.audio.policy.configuration.V7_1.Role source;
+  }
+
+  public class Routes {
+    ctor public Routes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Routes.Route> getRoute();
+  }
+
+  public static class Routes.Route {
+    ctor public Routes.Route();
+    method @Nullable public String getSink();
+    method @Nullable public String getSources();
+    method @Nullable public android.audio.policy.configuration.V7_1.MixType getType();
+    method public void setSink(@Nullable String);
+    method public void setSources(@Nullable String);
+    method public void setType(@Nullable android.audio.policy.configuration.V7_1.MixType);
+  }
+
+  public class SurroundFormats {
+    ctor public SurroundFormats();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.SurroundFormats.Format> getFormat();
+  }
+
+  public static class SurroundFormats.Format {
+    ctor public SurroundFormats.Format();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getSubformats();
+    method public void setName(@Nullable String);
+    method public void setSubformats(@Nullable java.util.List<java.lang.String>);
+  }
+
+  public class SurroundSound {
+    ctor public SurroundSound();
+    method @Nullable public android.audio.policy.configuration.V7_1.SurroundFormats getFormats();
+    method public void setFormats(@Nullable android.audio.policy.configuration.V7_1.SurroundFormats);
+  }
+
+  public enum Version {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.V7_1.Version _7_0;
+    enum_constant public static final android.audio.policy.configuration.V7_1.Version _7_1;
+  }
+
+  public class Volume {
+    ctor public Volume();
+    method @Nullable public android.audio.policy.configuration.V7_1.DeviceCategory getDeviceCategory();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method @Nullable public String getRef();
+    method @Nullable public android.audio.policy.configuration.V7_1.AudioStreamType getStream();
+    method public void setDeviceCategory(@Nullable android.audio.policy.configuration.V7_1.DeviceCategory);
+    method public void setRef(@Nullable String);
+    method public void setStream(@Nullable android.audio.policy.configuration.V7_1.AudioStreamType);
+  }
+
+  public class Volumes {
+    ctor public Volumes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Reference> getReference();
+    method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Volume> getVolume();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.audio.policy.configuration.V7_1.AudioPolicyConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/audio/7.1/config/api/last_current.txt b/audio/7.1/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/7.1/config/api/last_current.txt
diff --git a/audio/7.1/config/api/last_removed.txt b/audio/7.1/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/7.1/config/api/last_removed.txt
diff --git a/audio/7.1/config/api/removed.txt b/audio/7.1/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/7.1/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/7.1/config/audio_policy_configuration.xsd b/audio/7.1/config/audio_policy_configuration.xsd
new file mode 100644
index 0000000..defb506
--- /dev/null
+++ b/audio/7.1/config/audio_policy_configuration.xsd
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- List the config versions supported by audio policy. -->
+    <xs:simpleType name="version">
+        <xs:restriction base="xs:decimal">
+            <xs:enumeration value="7.0"/>
+            <xs:enumeration value="7.1"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="halVersion">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Version of the interface the hal implements. Note that this
+                relates to legacy HAL API versions since HIDL APIs are versioned
+                using other mechanisms.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:decimal">
+            <!-- List of HAL versions supported by the framework. -->
+            <xs:enumeration value="2.0"/>
+            <xs:enumeration value="3.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="audioPolicyConfiguration">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="globalConfiguration" type="globalConfiguration"/>
+                <xs:element name="modules" type="modules" maxOccurs="unbounded"/>
+                <xs:element name="volumes" type="volumes" maxOccurs="unbounded"/>
+                <xs:element name="surroundSound" type="surroundSound" minOccurs="0" />
+            </xs:sequence>
+            <xs:attribute name="version" type="version"/>
+        </xs:complexType>
+        <xs:key name="moduleNameKey">
+            <xs:selector xpath="modules/module"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:unique name="volumeTargetUniqueness">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@stream"/>
+            <xs:field xpath="@deviceCategory"/>
+        </xs:unique>
+        <xs:key name="volumeCurveNameKey">
+            <xs:selector xpath="volumes/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@ref"/>
+        </xs:keyref>
+    </xs:element>
+    <xs:complexType name="globalConfiguration">
+        <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+        <xs:attribute name="call_screen_mode_supported" type="xs:boolean" use="optional"/>
+        <xs:attribute name="engine_library" type="engineSuffix" use="optional"/>
+    </xs:complexType>
+    <xs:complexType name="modules">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                There should be one section per audio HW module present on the platform.
+                Each <module/> contains two mandatory tags: “halVersion” and “name”.
+                The module "name" is the same as in previous .conf file.
+                Each module must contain the following sections:
+                 - <devicePorts/>: a list of device descriptors for all
+                   input and output devices accessible via this module.
+                   This contains both permanently attached devices and removable devices.
+                 - <mixPorts/>: listing all output and input streams exposed by the audio HAL
+                 - <routes/>: list of possible connections between input
+                   and output devices or between stream and devices.
+                   A <route/> is defined by a set of 3 attributes:
+                        -"type": mux|mix means all sources are mutual exclusive (mux) or can be mixed (mix)
+                        -"sink": the sink involved in this route
+                        -"sources": all the sources than can be connected to the sink via this route
+                 - <attachedDevices/>: permanently attached devices.
+                   The attachedDevices section is a list of devices names.
+                   Their names correspond to device names defined in "devicePorts" section.
+                 - <defaultOutputDevice/> is the device to be used when no policy rule applies
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="module" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="attachedDevices" type="attachedDevices" minOccurs="0">
+                            <xs:unique name="attachedDevicesUniqueness">
+                                <xs:selector xpath="item"/>
+                                <xs:field xpath="."/>
+                            </xs:unique>
+                        </xs:element>
+                        <xs:element name="defaultOutputDevice" type="xs:token" minOccurs="0"/>
+                        <xs:element name="mixPorts" type="mixPorts" minOccurs="0"/>
+                        <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
+                        <xs:element name="routes" type="routes" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:string" use="required"/>
+                    <xs:attribute name="halVersion" type="halVersion" use="required"/>
+                </xs:complexType>
+                <xs:unique name="mixPortNameUniqueness">
+                    <xs:selector xpath="mixPorts/mixPort"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+                <xs:key name="devicePortNameKey">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@tagName"/>
+                </xs:key>
+                <xs:unique name="devicePortUniqueness">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@type"/>
+                    <xs:field xpath="@address"/>
+                </xs:unique>
+                <xs:keyref name="defaultOutputDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="defaultOutputDevice"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <xs:keyref name="attachedDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="attachedDevices/item"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <!-- The following 3 constraints try to make sure each sink port
+                     is reference in one an only one route. -->
+                <xs:key name="routeSinkKey">
+                    <!-- predicate [@type='sink'] does not work in xsd 1.0 -->
+                    <xs:selector xpath="devicePorts/devicePort|mixPorts/mixPort"/>
+                    <xs:field xpath="@tagName|@name"/>
+                </xs:key>
+                <xs:keyref name="routeSinkRef" refer="routeSinkKey">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:keyref>
+                <xs:unique name="routeUniqueness">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="attachedDevices">
+        <xs:sequence>
+            <xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioInOutFlag">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+              The flags indicate suggested stream attributes supported by the profile.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DEEP_BUFFER" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_NON_BLOCKING" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_TTS" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_RAW" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_SYNC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT_PCM" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_SPATIALIZER" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_SYNC" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_MMAP_NOIRQ" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioInOutFlags">
+        <xs:list itemType="audioInOutFlag" />
+    </xs:simpleType>
+    <xs:simpleType name="role">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="sink"/>
+            <xs:enumeration value="source"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="mixPorts">
+        <xs:sequence>
+            <xs:element name="mixPort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="flags" type="audioInOutFlags"/>
+                    <xs:attribute name="maxOpenCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="maxActiveCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="preferredUsage" type="audioUsageList">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                When choosing the mixPort of an audio track, the audioPolicy
+                                first considers the mixPorts with a preferredUsage including
+                                the track AudioUsage preferred .
+                                If non support the track format, the other mixPorts are considered.
+                                Eg: a <mixPort preferredUsage="AUDIO_USAGE_MEDIA" /> will receive
+                                    the audio of all apps playing with a MEDIA usage.
+                                    It may receive audio from ALARM if there are no audio compatible
+                                    <mixPort preferredUsage="AUDIO_USAGE_ALARM" />.
+                             </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                </xs:complexType>
+                <xs:unique name="mixPortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="mixPortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioDevice">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_DEVICE_NONE"/>
+
+            <xs:enumeration value="AUDIO_DEVICE_OUT_EARPIECE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_TELEPHONY_TX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_FM"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_BROADCAST"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
+
+            <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_EARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLE_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="vendorExtension">
+        <!-- Vendor extension names must be prefixed by "VX_" to distinguish them from
+             AOSP values. Vendors must namespace their names to avoid conflicts. The
+             namespace part must only use capital latin characters and decimal digits and
+             consist of at least 3 characters. The part of the extension name after the
+             namespace may in addition include underscores. Example for a hypothetical
+             Google virtual reality device:
+
+                 <devicePort tagName="VR" type="VX_GOOGLE_VR" role="sink" />
+        -->
+        <xs:restriction base="xs:string">
+            <xs:pattern value="VX_[A-Z0-9]{3,}_[_A-Z0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="extendableAudioDevice">
+        <xs:union memberTypes="audioDevice vendorExtension"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioFormat">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
+            <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_24_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_FLOAT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_24_BIT_PACKED"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_NB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+            <xs:enumeration value="AUDIO_FORMAT_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
+            <xs:enumeration value="AUDIO_FORMAT_DOLBY_TRUEHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRC"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCWB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCNW"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADIF"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA_PRO"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB_PLUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP2"/>
+            <xs:enumeration value="AUDIO_FORMAT_QCELP"/>
+            <xs:enumeration value="AUDIO_FORMAT_DSD"/>
+            <xs:enumeration value="AUDIO_FORMAT_FLAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_ALAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
+            <xs:enumeration value="AUDIO_FORMAT_SBC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC4"/>
+            <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_CELT"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE"/>
+            <xs:enumeration value="AUDIO_FORMAT_LHDC"/>
+            <xs:enumeration value="AUDIO_FORMAT_LHDC_LL"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_TWSP"/>
+            <xs:enumeration value="AUDIO_FORMAT_LC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L4"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
+            <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_UHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_DRA"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="extendableAudioFormat">
+        <xs:union memberTypes="audioFormat vendorExtension"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioUsage">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio usage specifies the intended use case for the sound being played.
+                Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN" />
+            <xs:enumeration value="AUDIO_USAGE_MEDIA" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            <xs:enumeration value="AUDIO_USAGE_ALARM" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_GAME" />
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT" />
+            <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT" />
+            <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+            <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+            <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+            <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioUsageList">
+        <xs:list itemType="audioUsage"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioContentType">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio content type expresses the general category of the content.
+                Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="samplingRates">
+        <xs:list itemType="xs:nonNegativeInteger" />
+    </xs:simpleType>
+    <xs:simpleType name="audioChannelMask">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio channel mask specifies presence of particular channels.
+                There are two representations:
+                - representation position (traditional discrete channel specification,
+                  e.g. "left", "right");
+                - indexed (this is similar to "tracks" in audio mixing, channels
+                  are represented using numbers).
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CHANNEL_NONE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_SIDE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_SURROUND"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_PENTA"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_SIDE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_6POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_13POINT_360RA"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_22POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_A"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_STEREO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_FRONT_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_5POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_CALL_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_3"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_5"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_7"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_8"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_9"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_10"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_11"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_12"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_13"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_14"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_15"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_16"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_17"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_18"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_19"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_20"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_21"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_22"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_23"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_24"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="channelMasks">
+        <xs:list itemType="audioChannelMask" />
+    </xs:simpleType>
+    <xs:simpleType name="audioEncapsulationType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_NONE"/>
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_IEC61937"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="profile">
+        <xs:attribute name="name" type="xs:token" use="optional"/>
+        <xs:attribute name="format" type="extendableAudioFormat" use="optional"/>
+        <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+        <xs:attribute name="channelMasks" type="channelMasks" use="optional"/>
+        <xs:attribute name="encapsulationType" type="audioEncapsulationType" use="optional"/>
+    </xs:complexType>
+    <xs:simpleType name="audioGainMode">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioGainModeMaskUnrestricted">
+        <xs:list itemType="audioGainMode" />
+    </xs:simpleType>
+    <xs:simpleType name='audioGainModeMask'>
+        <xs:restriction base='audioGainModeMaskUnrestricted'>
+            <xs:minLength value='1' />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="gains">
+        <xs:sequence>
+            <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="mode" type="audioGainModeMask" use="required"/>
+                    <xs:attribute name="channel_mask" type="audioChannelMask" use="optional"/>
+                    <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="useForVolume" type="xs:boolean" use="optional"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="devicePorts">
+        <xs:sequence>
+            <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="tagName" type="xs:token" use="required"/>
+                    <xs:attribute name="type" type="extendableAudioDevice" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="address" type="xs:string" use="optional" default=""/>
+                    <!-- Note that XSD 1.0 can not check that a type only has one default. -->
+                    <xs:attribute name="default" type="xs:boolean" use="optional">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                The default device will be used if multiple have the same type
+                                and no explicit route request exists for a specific device of
+                                that type.
+                            </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                    <xs:attribute name="encodedFormats" type="audioFormatsList" use="optional"
+                                  default="" />
+                </xs:complexType>
+                <xs:unique name="devicePortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="devicePortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="mixType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="mix"/>
+            <xs:enumeration value="mux"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="routes">
+        <xs:sequence>
+            <xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+                <xs:annotation>
+                    <xs:documentation xml:lang="en">
+                        List all available sources for a given sink.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                    <xs:attribute name="type" type="mixType" use="required"/>
+                    <xs:attribute name="sink" type="xs:string" use="required"/>
+                    <xs:attribute name="sources" type="xs:string" use="required"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="volumes">
+        <xs:sequence>
+            <xs:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="reference" type="reference" minOccurs="0" maxOccurs="unbounded">
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- TODO: Always require a ref for better xsd validations.
+               Currently a volume could have no points nor ref
+               as it can not be forbidden by xsd 1.0.-->
+    <xs:simpleType name="volumePoint">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma separated pair of number.
+                The fist one is the framework level (between 0 and 100).
+                The second one is the volume to send to the HAL.
+                The framework will interpolate volumes not specified.
+                Their MUST be at least 2 points specified.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioStreamType">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio stream type describing the intended use case of a stream.
+                Please consult frameworks/base/media/java/android/media/AudioSystem.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+            <xs:enumeration value="AUDIO_STREAM_RING"/>
+            <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+            <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+            <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+            <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+            <xs:enumeration value="AUDIO_STREAM_TTS"/>
+            <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
+            <xs:enumeration value="AUDIO_STREAM_PATCH"/>
+            <xs:enumeration value="AUDIO_STREAM_CALL_ASSISTANT"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioSource">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                An audio source defines the intended use case for the sound being recorded.
+                Please consult frameworks/base/media/java/android/media/MediaRecorder.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_SOURCE_DEFAULT"/>
+            <xs:enumeration value="AUDIO_SOURCE_MIC"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_UPLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_SOURCE_CAMCORDER"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_SOURCE_UNPROCESSED"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_SOURCE_HOTWORD"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of device_category from Volume.h. -->
+    <xs:simpleType name="deviceCategory">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+            <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+            <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="volume">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Volume section defines a volume curve for a given use case and device category.
+                It contains a list of points of this curve expressing the attenuation in Millibels
+                for a given volume index from 0 to 100.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </volume>
+
+                It may also reference a reference/@name to avoid duplicating curves.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
+                        ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </reference>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="stream" type="audioStreamType"/>
+        <xs:attribute name="deviceCategory" type="deviceCategory"/>
+        <xs:attribute name="ref" type="xs:token" use="optional"/>
+    </xs:complexType>
+    <xs:complexType name="reference">
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="surroundSound">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Surround Sound section provides configuration related to handling of
+                multi-channel formats.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="formats" type="surroundFormats"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioFormatsList">
+        <xs:list itemType="extendableAudioFormat" />
+    </xs:simpleType>
+    <xs:complexType name="surroundFormats">
+        <xs:sequence>
+            <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="extendableAudioFormat" use="required"/>
+                    <xs:attribute name="subformats" type="audioFormatsList" />
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="engineSuffix">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="default"/>
+            <xs:enumeration value="configurable"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/audio/7.1/types.hal b/audio/7.1/types.hal
new file mode 100644
index 0000000..9d8ee4d
--- /dev/null
+++ b/audio/7.1/types.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 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.audio@7.1;
+
+/**
+ * Latency modes used for the variable latency feature on output streams.
+ * Used by setLatencyMode() and getRecommendedLatencyModes() methods.
+ */
+
+@export(name="audio_latency_mode_t", value_prefix="AUDIO_LATENCY_MODE_")
+enum LatencyMode : int32_t {
+    /** No specific constraint on the latency */
+    FREE = 0,
+    /** A relatively low latency compatible with head tracking operation (e.g less than 100ms) */
+    LOW = 1,
+};
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index c172674..6a0cfa5 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -47,6 +47,11 @@
             vndk: {
                 enabled: true,
             },
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.bluetooth",
+            ],
+            min_sdk_version: "31",
         },
     },
     versions: [
diff --git a/audio/common/7.1/Android.bp b/audio/common/7.1/Android.bp
new file mode 100644
index 0000000..a257510
--- /dev/null
+++ b/audio/common/7.1/Android.bp
@@ -0,0 +1,23 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "android.hardware.audio.common@7.1-enums",
+    vendor_available: true,
+    generated_headers: ["audio_policy_configuration_V7_1_enums"],
+    generated_sources: ["audio_policy_configuration_V7_1_enums"],
+    header_libs: ["libxsdc-utils"],
+    export_generated_headers: ["audio_policy_configuration_V7_1_enums"],
+    export_header_lib_headers: ["libxsdc-utils"],
+    export_include_dirs: ["enums/include"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+}
diff --git a/audio/common/7.1/enums/OWNERS b/audio/common/7.1/enums/OWNERS
new file mode 100644
index 0000000..24071af
--- /dev/null
+++ b/audio/common/7.1/enums/OWNERS
@@ -0,0 +1,2 @@
+elaurent@google.com
+mnaganov@google.com
diff --git a/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h b/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h
new file mode 100644
index 0000000..6f6a0ca
--- /dev/null
+++ b/audio/common/7.1/enums/include/android_audio_policy_configuration_V7_1-enums.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
+#define ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
+
+#include <sys/types.h>
+#include <regex>
+#include <string>
+
+#include <android_audio_policy_configuration_V7_1_enums.h>
+
+namespace android::audio::policy::configuration::V7_1 {
+
+static inline size_t getChannelCount(AudioChannelMask mask) {
+    switch (mask) {
+        case AudioChannelMask::AUDIO_CHANNEL_NONE:
+            return 0;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_MONO:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1:
+            return 1;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2:
+            return 2;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3:
+            return 3;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4:
+            return 4;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5:
+            return 5;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_6:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6:
+            return 6;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7:
+            return 7;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8:
+            return 8;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9:
+            return 9;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4:
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10:
+            return 10;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11:
+            return 11;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
+            return 12;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_13POINT_360RA:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
+            return 13;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_9POINT1POINT4:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
+            return 14;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15:
+            return 15;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_9POINT1POINT6:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16:
+            return 16;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17:
+            return 17;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18:
+            return 18;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19:
+            return 19;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20:
+            return 20;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21:
+            return 21;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22:
+            return 22;
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
+            return 23;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_22POINT2:
+        case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
+            return 24;
+        case AudioChannelMask::UNKNOWN:
+            return 0;
+            // No default to make sure all cases are covered.
+    }
+    // This is to avoid undefined behavior if 'mask' isn't a valid enum value.
+    return 0;
+}
+
+static inline ssize_t getChannelCount(const std::string& mask) {
+    return getChannelCount(stringToAudioChannelMask(mask));
+}
+
+static inline bool isOutputDevice(AudioDevice device) {
+    switch (device) {
+        case AudioDevice::UNKNOWN:
+        case AudioDevice::AUDIO_DEVICE_NONE:
+            return false;
+        case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE:
+        case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
+        case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+        case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL:
+        case AudioDevice::AUDIO_DEVICE_OUT_HDMI:
+        case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY:
+        case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE:
+        case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+        case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
+        case AudioDevice::AUDIO_DEVICE_OUT_LINE:
+        case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
+        case AudioDevice::AUDIO_DEVICE_OUT_HDMI_EARC:
+        case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
+        case AudioDevice::AUDIO_DEVICE_OUT_FM:
+        case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
+        case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE:
+        case AudioDevice::AUDIO_DEVICE_OUT_IP:
+        case AudioDevice::AUDIO_DEVICE_OUT_BUS:
+        case AudioDevice::AUDIO_DEVICE_OUT_PROXY:
+        case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID:
+        case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER:
+        case AudioDevice::AUDIO_DEVICE_OUT_BLE_BROADCAST:
+        case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
+        case AudioDevice::AUDIO_DEVICE_OUT_STUB:
+            return true;
+        case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION:
+        case AudioDevice::AUDIO_DEVICE_IN_AMBIENT:
+        case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC:
+        case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL:
+        case AudioDevice::AUDIO_DEVICE_IN_HDMI:
+        case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL:
+        case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX:
+        case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC:
+        case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX:
+        case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY:
+        case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE:
+        case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER:
+        case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER:
+        case AudioDevice::AUDIO_DEVICE_IN_LINE:
+        case AudioDevice::AUDIO_DEVICE_IN_SPDIF:
+        case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
+        case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK:
+        case AudioDevice::AUDIO_DEVICE_IN_IP:
+        case AudioDevice::AUDIO_DEVICE_IN_BUS:
+        case AudioDevice::AUDIO_DEVICE_IN_PROXY:
+        case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
+        case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
+        case AudioDevice::AUDIO_DEVICE_IN_HDMI_EARC:
+        case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
+        case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET:
+        case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
+        case AudioDevice::AUDIO_DEVICE_IN_STUB:
+            return false;
+            // No default to make sure all cases are covered.
+    }
+    // This is to avoid undefined behavior if 'device' isn't a valid enum value.
+    return false;
+}
+
+static inline bool isOutputDevice(const std::string& device) {
+    return isOutputDevice(stringToAudioDevice(device));
+}
+
+static inline bool isTelephonyDevice(AudioDevice device) {
+    return device == AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX ||
+           device == AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX;
+}
+
+static inline bool isTelephonyDevice(const std::string& device) {
+    return isTelephonyDevice(stringToAudioDevice(device));
+}
+
+static inline bool maybeVendorExtension(const std::string& s) {
+    // Only checks whether the string starts with the "vendor prefix".
+    static const std::string vendorPrefix = "VX_";
+    return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
+}
+
+static inline bool isVendorExtension(const std::string& s) {
+    // Must be the same as the "vendorExtension" rule from the XSD file.
+    static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
+    return std::regex_match(s.begin(), s.end(), vendorExtension);
+}
+
+static inline bool isUnknownAudioChannelMask(const std::string& mask) {
+    return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN;
+}
+
+static inline bool isUnknownAudioContentType(const std::string& contentType) {
+    return stringToAudioContentType(contentType) == AudioContentType::UNKNOWN;
+}
+
+static inline bool isUnknownAudioDevice(const std::string& device) {
+    return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device);
+}
+
+static inline bool isUnknownAudioFormat(const std::string& format) {
+    return stringToAudioFormat(format) == AudioFormat::UNKNOWN && !isVendorExtension(format);
+}
+
+static inline bool isUnknownAudioGainMode(const std::string& mode) {
+    return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN;
+}
+
+static inline bool isUnknownAudioInOutFlag(const std::string& flag) {
+    return stringToAudioInOutFlag(flag) == AudioInOutFlag::UNKNOWN;
+}
+
+static inline bool isUnknownAudioSource(const std::string& source) {
+    return stringToAudioSource(source) == AudioSource::UNKNOWN;
+}
+
+static inline bool isUnknownAudioStreamType(const std::string& streamType) {
+    return stringToAudioStreamType(streamType) == AudioStreamType::UNKNOWN;
+}
+
+static inline bool isUnknownAudioUsage(const std::string& usage) {
+    return stringToAudioUsage(usage) == AudioUsage::UNKNOWN;
+}
+
+static inline bool isLinearPcm(AudioFormat format) {
+    switch (format) {
+        case AudioFormat::AUDIO_FORMAT_PCM_16_BIT:
+        case AudioFormat::AUDIO_FORMAT_PCM_8_BIT:
+        case AudioFormat::AUDIO_FORMAT_PCM_32_BIT:
+        case AudioFormat::AUDIO_FORMAT_PCM_8_24_BIT:
+        case AudioFormat::AUDIO_FORMAT_PCM_FLOAT:
+        case AudioFormat::AUDIO_FORMAT_PCM_24_BIT_PACKED:
+            return true;
+        default:
+            return false;
+    }
+}
+
+static inline bool isLinearPcm(const std::string& format) {
+    return isLinearPcm(stringToAudioFormat(format));
+}
+
+static inline bool isUnknownAudioEncapsulationType(const std::string& encapsulationType) {
+    return stringToAudioEncapsulationType(encapsulationType) == AudioEncapsulationType::UNKNOWN;
+}
+
+}  // namespace android::audio::policy::configuration::V7_1
+
+#endif  // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_1__ENUMS_H
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 5a5b5d2..218d7c0 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -21,7 +21,7 @@
 #define LOG_TAG "HidlUtils"
 #include <log/log.h>
 
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
 #include <common/all-versions/HidlSupport.h>
 #include <common/all-versions/VersionUtils.h>
 
@@ -31,11 +31,11 @@
 namespace hardware {
 namespace audio {
 namespace common {
-namespace CPP_VERSION {
+namespace COMMON_TYPES_CPP_VERSION {
 namespace implementation {
 
 namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
 }
 
 #define CONVERT_CHECKED(expr, result)                   \
@@ -1151,7 +1151,7 @@
 }
 
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace COMMON_TYPES_CPP_VERSION
 }  // namespace common
 }  // namespace audio
 }  // namespace hardware
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 98ecc07..ad9dee2 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -17,7 +17,9 @@
 #ifndef android_hardware_audio_Hidl_Utils_H_
 #define android_hardware_audio_Hidl_Utils_H_
 
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
 
 #include <memory>
 #include <string>
@@ -29,11 +31,11 @@
 namespace hardware {
 namespace audio {
 namespace common {
-namespace CPP_VERSION {
+namespace COMMON_TYPES_CPP_VERSION {
 namespace implementation {
 
 using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 
 struct HidlUtils {
     static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput,
@@ -267,7 +269,7 @@
 #endif  // MAJOR_VERSION <= 6
 
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace COMMON_TYPES_CPP_VERSION
 }  // namespace common
 }  // namespace audio
 }  // namespace hardware
diff --git a/audio/common/all-versions/default/UuidUtils.h b/audio/common/all-versions/default/UuidUtils.h
index cd04fb0..4a64f0a 100644
--- a/audio/common/all-versions/default/UuidUtils.h
+++ b/audio/common/all-versions/default/UuidUtils.h
@@ -20,7 +20,7 @@
 #include <string>
 
 // clang-format off
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
 #include <system/audio.h>
@@ -32,7 +32,7 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 
 class UuidUtils {
   public:
diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h
index 9bfca0c..9771374 100644
--- a/audio/common/all-versions/default/VersionUtils.h
+++ b/audio/common/all-versions/default/VersionUtils.h
@@ -17,7 +17,30 @@
 #ifndef ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
 #define ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
 
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// A workaround for b/216149583 (vendor code having its own copy of VersionMacro.h)
+#ifndef COMMON_TYPES_MINOR_VERSION
+#define COMMON_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+#ifndef CORE_TYPES_MINOR_VERSION
+#define CORE_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+#ifndef COMMON_TYPES_FILE_VERSION
+#define COMMON_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., COMMON_TYPES_MINOR_VERSION)
+#endif
+#ifndef CORE_TYPES_FILE_VERSION
+#define CORE_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., CORE_TYPES_MINOR_VERSION)
+#endif
+#ifndef COMMON_TYPES_CPP_VERSION
+#define COMMON_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, COMMON_TYPES_MINOR_VERSION)
+#endif
+#ifndef CORE_TYPES_CPP_VERSION
+#define CORE_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, CORE_TYPES_MINOR_VERSION)
+#endif
+// End of workaround
+
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
 
 namespace android {
 namespace hardware {
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 89585b0..e26369f 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -66,6 +66,7 @@
     const std::vector<InterfacesList> mandatoryInterfaces = {
         {
             "Audio Core API",
+            "android.hardware.audio@7.1::IDevicesFactory",
             "android.hardware.audio@7.0::IDevicesFactory",
             "android.hardware.audio@6.0::IDevicesFactory",
             "android.hardware.audio@5.0::IDevicesFactory",
diff --git a/audio/common/all-versions/default/tests/hidlutils6_tests.cpp b/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
index 3a24e75..ca59b9d 100644
--- a/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils6_tests.cpp
@@ -23,14 +23,14 @@
 #include <system/audio.h>
 
 using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 
 // Not generated automatically because DeviceAddress contains
 // an union.
 //
 // operator== must be defined in the same namespace as the data type.
-namespace android::hardware::audio::common::CPP_VERSION {
+namespace android::hardware::audio::common::COMMON_TYPES_CPP_VERSION {
 
 inline bool operator==(const DeviceAddress& lhs, const DeviceAddress& rhs) {
     if (lhs.device != rhs.device) return false;
@@ -49,7 +49,7 @@
     return lhs.busAddress == rhs.busAddress;
 }
 
-}  // namespace android::hardware::audio::common::CPP_VERSION
+}  // namespace android::hardware::audio::common::COMMON_TYPES_CPP_VERSION
 
 static void ConvertDeviceAddress(const DeviceAddress& device) {
     audio_devices_t halDeviceType;
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index c9e6fac..2749cce 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -29,8 +29,8 @@
 
 using namespace android;
 using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 namespace xsd {
 using namespace ::android::audio::policy::configuration::V7_0;
 }
diff --git a/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h b/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
index dc54cee..875e167 100644
--- a/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
+++ b/audio/common/all-versions/util/include/common/all-versions/VersionMacro.h
@@ -21,6 +21,14 @@
 #error "MAJOR_VERSION and MINOR_VERSION must be defined"
 #endif
 
+#ifndef COMMON_TYPES_MINOR_VERSION
+#define COMMON_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+
+#ifndef CORE_TYPES_MINOR_VERSION
+#define CORE_TYPES_MINOR_VERSION MINOR_VERSION
+#endif
+
 /** Allows macro expansion for x and add surrounding `<>`.
  * Is intended to be used for version dependant includes as
  * `#include` do not macro expand if starting with < or "
@@ -34,10 +42,30 @@
 #define EXPAND_CONCAT_3(a, b, c) CONCAT_3(a, b, c)
 /** The directory name of the version: <major>.<minor> */
 #define FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., MINOR_VERSION)
+#define COMMON_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., COMMON_TYPES_MINOR_VERSION)
+#define CORE_TYPES_FILE_VERSION EXPAND_CONCAT_3(MAJOR_VERSION, ., CORE_TYPES_MINOR_VERSION)
 
 #define CONCAT_4(a, b, c, d) a##b##c##d
 #define EXPAND_CONCAT_4(a, b, c, d) CONCAT_4(a, b, c, d)
 /** The c++ namespace of the version: V<major>_<minor> */
 #define CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, MINOR_VERSION)
+#define COMMON_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, COMMON_TYPES_MINOR_VERSION)
+#define CORE_TYPES_CPP_VERSION EXPAND_CONCAT_4(V, MAJOR_VERSION, _, CORE_TYPES_MINOR_VERSION)
+
+/* Gluing these file names from macros is non-trivial due to "illegal tokens"
+   occurring during expansion. The XSD and enums always use the minor version. */
+// clang-format off
+#if MAJOR_VERSION >= 7
+#if MINOR_VERSION == 0
+#define APM_XSD_H_FILENAME android_audio_policy_configuration_V7_0.h
+#define APM_XSD_ENUMS_H_FILENAME android_audio_policy_configuration_V7_0-enums.h
+#elif MINOR_VERSION == 1
+#define APM_XSD_H_FILENAME android_audio_policy_configuration_V7_1.h
+#define APM_XSD_ENUMS_H_FILENAME android_audio_policy_configuration_V7_1-enums.h
+#else
+#error "Unsupported minor version"
+#endif
+#endif
+// clang-format on
 
 #endif  // ANDROID_HARDWARE_VERSION_MACRO_H
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 8fb7111..86380a5 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -159,3 +159,29 @@
     name: "android.hardware.audio@7.0-impl",
     defaults: ["android.hardware.audio@7.0-impl_default"],
 }
+
+cc_defaults {
+    name: "android.hardware.audio@7.1-impl_default",
+    defaults: ["android.hardware.audio-impl_default"],
+    shared_libs: [
+        "android.hardware.audio@7.0",
+        "android.hardware.audio@7.1",
+        "android.hardware.audio@7.0-util",
+        "android.hardware.audio.common@7.0",
+        "android.hardware.audio.common@7.1-enums",
+        "android.hardware.audio.common@7.0-util",
+        "libbase",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=7",
+        "-DMINOR_VERSION=1",
+        "-DCOMMON_TYPES_MINOR_VERSION=0",
+        "-DCORE_TYPES_MINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.audio@7.1-impl",
+    defaults: ["android.hardware.audio@7.1-impl_default"],
+}
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 130dfba..98a59b9 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -39,7 +39,10 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
 
 Device::Device(audio_hw_device_t* device) : mIsClosed(false), mDevice(device) {}
 
@@ -82,7 +85,7 @@
     if (mDevice->set_master_volume == NULL) {
         return Result::NOT_SUPPORTED;
     }
-    if (!isGainNormalized(volume)) {
+    if (!util::isGainNormalized(volume)) {
         ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
         return Result::INVALID_ARGUMENTS;
     }
@@ -148,7 +151,7 @@
     return Void();
 }
 
-std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle,
+std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamCore(int32_t ioHandle,
                                                                 const DeviceAddress& device,
                                                                 const AudioConfig& config,
                                                                 const AudioOutputFlags& flags,
@@ -185,7 +188,7 @@
     return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
 }
 
-std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
+std::tuple<Result, sp<IStreamIn>> Device::openInputStreamCore(
         int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
         const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) {
     audio_config_t halConfig;
@@ -228,7 +231,7 @@
                                       openOutputStream_cb _hidl_cb) {
     AudioConfig suggestedConfig;
     auto [result, streamOut] =
-        openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+            openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig);
     _hidl_cb(result, streamOut, suggestedConfig);
     return Void();
 }
@@ -238,12 +241,36 @@
                                      AudioSource source, openInputStream_cb _hidl_cb) {
     AudioConfig suggestedConfig;
     auto [result, streamIn] =
-        openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+            openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig);
     _hidl_cb(result, streamIn, suggestedConfig);
     return Void();
 }
 
 #elif MAJOR_VERSION >= 4
+std::tuple<Result, sp<IStreamOut>, AudioConfig> Device::openOutputStreamImpl(
+        int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+        const SourceMetadata& sourceMetadata,
+#if MAJOR_VERSION <= 6
+        AudioOutputFlags flags) {
+    if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr);
+        status != NO_ERROR) {
+#else
+        const AudioOutputFlags& flags) {
+    if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata,
+                                                           false /*ignoreNonVendorTags*/, nullptr);
+        status != NO_ERROR) {
+#endif
+        return {analyzeStatus("sourceMetadataToHal", status), nullptr, {}};
+    }
+    AudioConfig suggestedConfig;
+    auto [result, streamOut] =
+            openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig);
+    if (streamOut) {
+        streamOut->updateSourceMetadata(sourceMetadata);
+    }
+    return {result, streamOut, suggestedConfig};
+}
+
 Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                       const AudioConfig& config,
 #if MAJOR_VERSION <= 6
@@ -253,27 +280,46 @@
 #endif
                                       const SourceMetadata& sourceMetadata,
                                       openOutputStream_cb _hidl_cb) {
-#if MAJOR_VERSION <= 6
-    if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr);
-        status != NO_ERROR) {
-#else
-    if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata,
-                                                           false /*ignoreNonVendorTags*/, nullptr);
-        status != NO_ERROR) {
-#endif
-        _hidl_cb(analyzeStatus("sourceMetadataToHal", status), nullptr, AudioConfig{});
-        return Void();
-    }
-    AudioConfig suggestedConfig;
-    auto [result, streamOut] =
-        openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
-    if (streamOut) {
-        streamOut->updateSourceMetadata(sourceMetadata);
-    }
+    auto [result, streamOut, suggestedConfig] =
+            openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags);
     _hidl_cb(result, streamOut, suggestedConfig);
     return Void();
 }
 
+std::tuple<Result, sp<IStreamIn>, AudioConfig> Device::openInputStreamImpl(
+        int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+#if MAJOR_VERSION <= 6
+        AudioInputFlags flags,
+#else
+        const AudioInputFlags& flags,
+#endif
+        const SinkMetadata& sinkMetadata) {
+    if (sinkMetadata.tracks.size() == 0) {
+        // This should never happen, the framework must not create as stream
+        // if there is no client
+        ALOGE("openInputStream called without tracks connected");
+        return {Result::INVALID_ARGUMENTS, nullptr, AudioConfig{}};
+    }
+#if MAJOR_VERSION <= 6
+    if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
+#else
+    if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
+                                                         false /*ignoreNonVendorTags*/, nullptr);
+        status != NO_ERROR) {
+#endif
+        return {analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}};
+    }
+    // Pick the first one as the main.
+    AudioSource source = sinkMetadata.tracks[0].source;
+    AudioConfig suggestedConfig;
+    auto [result, streamIn] =
+            openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig);
+    if (streamIn) {
+        streamIn->updateSinkMetadata(sinkMetadata);
+    }
+    return {result, streamIn, suggestedConfig};
+}
+
 Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
                                      const AudioConfig& config,
 #if MAJOR_VERSION <= 6
@@ -283,36 +329,35 @@
 #endif
                                      const SinkMetadata& sinkMetadata,
                                      openInputStream_cb _hidl_cb) {
-    if (sinkMetadata.tracks.size() == 0) {
-        // This should never happen, the framework must not create as stream
-        // if there is no client
-        ALOGE("openInputStream called without tracks connected");
-        _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig{});
-        return Void();
-    }
-#if MAJOR_VERSION <= 6
-    if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
-#else
-    if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
-                                                         false /*ignoreNonVendorTags*/, nullptr);
-        status != NO_ERROR) {
-#endif
-        _hidl_cb(analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{});
-        return Void();
-    }
-    // Pick the first one as the main.
-    AudioSource source = sinkMetadata.tracks[0].source;
-    AudioConfig suggestedConfig;
-    auto [result, streamIn] =
-        openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
-    if (streamIn) {
-        streamIn->updateSinkMetadata(sinkMetadata);
-    }
+    auto [result, streamIn, suggestedConfig] =
+            openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata);
     _hidl_cb(result, streamIn, suggestedConfig);
     return Void();
 }
 #endif /* MAJOR_VERSION */
 
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> Device::openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                          const AudioConfig& config, const AudioOutputFlags& flags,
+                                          const SourceMetadata& sourceMetadata,
+                                          openOutputStream_7_1_cb _hidl_cb) {
+    auto [result, streamOut, suggestedConfig] =
+            openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags);
+    _hidl_cb(result, streamOut, suggestedConfig);
+    return Void();
+}
+
+Return<void> Device::openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                         const AudioConfig& config, const AudioInputFlags& flags,
+                                         const SinkMetadata& sinkMetadata,
+                                         openInputStream_7_1_cb _hidl_cb) {
+    auto [result, streamIn, suggestedConfig] =
+            openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata);
+    _hidl_cb(result, streamIn, suggestedConfig);
+    return Void();
+}
+#endif  // V7.1
+
 Return<bool> Device::supportsAudioPatches() {
     return version() >= AUDIO_DEVICE_API_VERSION_3_0;
 }
diff --git a/audio/core/all-versions/default/DevicesFactory.cpp b/audio/core/all-versions/default/DevicesFactory.cpp
index 729f18c..f44daf0 100644
--- a/audio/core/all-versions/default/DevicesFactory.cpp
+++ b/audio/core/all-versions/default/DevicesFactory.cpp
@@ -47,22 +47,54 @@
     _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
     return Void();
 }
+
+Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
+    return openDevice<implementation::Device>(moduleName, _hidl_cb);
+}
 #elif MAJOR_VERSION >= 4
 Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
     if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
         return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
     }
-    return openDevice(moduleName.c_str(), _hidl_cb);
+    return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb);
 }
 Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
     return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
 }
 #endif
 
-Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
-    return openDevice<implementation::Device>(moduleName, _hidl_cb);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> DevicesFactory::openDevice_7_1(const hidl_string& moduleName,
+                                            openDevice_7_1_cb _hidl_cb) {
+    if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+        Result result;
+        sp<IPrimaryDevice> primary;
+        auto ret = openDevice<PrimaryDevice>(
+                AUDIO_HARDWARE_MODULE_ID_PRIMARY,
+                [&result, &primary](Result r, const sp<IPrimaryDevice>& p) {
+                    result = r;
+                    primary = p;
+                });
+        if (ret.isOk() && result == Result::OK && primary != nullptr) {
+            auto getDeviceRet = primary->getDevice();
+            if (getDeviceRet.isOk()) {
+                _hidl_cb(result, getDeviceRet);
+            } else {
+                _hidl_cb(Result::NOT_INITIALIZED, nullptr);
+            }
+        } else {
+            _hidl_cb(result, nullptr);
+        }
+        return Void();
+    }
+    return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb);
 }
 
+Return<void> DevicesFactory::openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) {
+    return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
+}
+#endif  // V7.1
+
 template <class DeviceShim, class Callback>
 Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
     audio_hw_device_t* halDevice;
diff --git a/audio/core/all-versions/default/ParametersUtil.cpp b/audio/core/all-versions/default/ParametersUtil.cpp
index 4d53645..e21eff2 100644
--- a/audio/core/all-versions/default/ParametersUtil.cpp
+++ b/audio/core/all-versions/default/ParametersUtil.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
 namespace implementation {
 
 /** Converts a status_t in Result according to the rules of AudioParameter::get*
@@ -168,7 +168,7 @@
 }
 
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace CORE_TYPES_CPP_VERSION
 }  // namespace audio
 }  // namespace hardware
 }  // namespace android
diff --git a/audio/core/all-versions/default/PrimaryDevice.cpp b/audio/core/all-versions/default/PrimaryDevice.cpp
index fe56177..cf162f1 100644
--- a/audio/core/all-versions/default/PrimaryDevice.cpp
+++ b/audio/core/all-versions/default/PrimaryDevice.cpp
@@ -29,6 +29,10 @@
 namespace CPP_VERSION {
 namespace implementation {
 
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
+
 PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
 
 PrimaryDevice::~PrimaryDevice() {
@@ -195,7 +199,7 @@
 
 // Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
-    if (!isGainNormalized(volume)) {
+    if (!util::isGainNormalized(volume)) {
         ALOGW("Can not set a voice volume (%f) outside [0,1]", volume);
         return Result::INVALID_ARGUMENTS;
     }
@@ -326,7 +330,7 @@
     return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz));
 }
 Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
-    if (!isGainNormalized(volume)) {
+    if (!util::isGainNormalized(volume)) {
         ALOGW("Can not set BT HFP volume (%f) outside [0,1]", volume);
         return Result::INVALID_ARGUMENTS;
     }
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index 7e32573..8e85a8b 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -37,8 +37,12 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 using ::android::hardware::audio::common::utils::splitString;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
 
 Stream::Stream(bool isInput, audio_stream_t* stream) : mIsInput(isInput), mStream(stream) {
     (void)mIsInput;  // prevent 'unused field' warnings in pre-V7 versions.
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 2aeee43..2bea425 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -37,7 +37,11 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
 
 namespace {
 
@@ -348,7 +352,7 @@
 }
 
 Return<Result> StreamIn::setGain(float gain) {
-    if (!isGainNormalized(gain)) {
+    if (!util::isGainNormalized(gain)) {
         ALOGW("Can not set a stream input gain (%f) outside [0,1]", gain);
         return Result::INVALID_ARGUMENTS;
     }
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index d027231..09df4ed 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -39,7 +39,11 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+namespace util {
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
+}
 
 namespace {
 
@@ -334,7 +338,7 @@
     if (mStream->set_volume == NULL) {
         return Result::NOT_SUPPORTED;
     }
-    if (!isGainNormalized(left)) {
+    if (!util::isGainNormalized(left)) {
         ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left, right);
         return Result::INVALID_ARGUMENTS;
     }
@@ -757,6 +761,73 @@
     ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str());
     return 0;
 }
+
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<Result> StreamOut::setLatencyMode(LatencyMode mode) {
+    return mStream->set_latency_mode != nullptr
+                   ? Stream::analyzeStatus(
+                             "set_latency_mode",
+                             mStream->set_latency_mode(mStream,
+                                                       static_cast<audio_latency_mode_t>(mode)))
+                   : Result::NOT_SUPPORTED;
+};
+
+Return<void> StreamOut::getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) {
+    Result retval = Result::NOT_SUPPORTED;
+    hidl_vec<LatencyMode> hidlModes;
+    size_t num_modes = AUDIO_LATENCY_MODE_CNT;
+    audio_latency_mode_t modes[AUDIO_LATENCY_MODE_CNT];
+
+    if (mStream->get_recommended_latency_modes != nullptr &&
+        mStream->get_recommended_latency_modes(mStream, &modes[0], &num_modes) == 0) {
+        if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) {
+            ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes);
+            retval = Result::INVALID_STATE;
+        } else {
+            hidlModes.resize(num_modes);
+            for (size_t i = 0; i < num_modes; ++i) {
+                hidlModes[i] = static_cast<LatencyMode>(modes[i]);
+            }
+            retval = Result::OK;
+        }
+    }
+    _hidl_cb(retval, hidlModes);
+    return Void();
+};
+
+// static
+void StreamOut::latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie) {
+    StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
+    sp<IStreamOutLatencyModeCallback> callback = self->mLatencyModeCallback.load();
+    if (callback.get() == nullptr) return;
+
+    ALOGV("%s", __func__);
+
+    if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) {
+        ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes);
+        return;
+    }
+
+    hidl_vec<LatencyMode> hidlModes(num_modes);
+    for (size_t i = 0; i < num_modes; ++i) {
+        hidlModes[i] = static_cast<LatencyMode>(modes[i]);
+    }
+    Return<void> result = callback->onRecommendedLatencyModeChanged(hidlModes);
+    ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str());
+}
+
+Return<Result> StreamOut::setLatencyModeCallback(
+        const sp<IStreamOutLatencyModeCallback>& callback) {
+    if (mStream->set_latency_mode_callback == nullptr) return Result::NOT_SUPPORTED;
+    int result = mStream->set_latency_mode_callback(mStream, StreamOut::latencyModeCallback, this);
+    if (result == 0) {
+        mLatencyModeCallback = callback;
+    }
+    return Stream::analyzeStatus("set_latency_mode_callback", result, {ENOSYS} /*ignore*/);
+};
+
+#endif
+
 #endif
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index 94cad53..0aeb6b3 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -44,7 +44,10 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 using AudioInputFlags = CoreUtils::AudioInputFlags;
 using AudioOutputFlags = CoreUtils::AudioOutputFlags;
@@ -63,14 +66,32 @@
     Return<void> getInputBufferSize(const AudioConfig& config,
                                     getInputBufferSize_cb _hidl_cb) override;
 
-    std::tuple<Result, sp<IStreamOut>> openOutputStreamImpl(int32_t ioHandle,
+    std::tuple<Result, sp<IStreamOut>> openOutputStreamCore(int32_t ioHandle,
                                                             const DeviceAddress& device,
                                                             const AudioConfig& config,
                                                             const AudioOutputFlags& flags,
                                                             AudioConfig* suggestedConfig);
-    std::tuple<Result, sp<IStreamIn>> openInputStreamImpl(
+    std::tuple<Result, sp<IStreamIn>> openInputStreamCore(
             int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
             const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig);
+#if MAJOR_VERSION >= 4
+    std::tuple<Result, sp<IStreamOut>, AudioConfig> openOutputStreamImpl(
+            int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+            const SourceMetadata& sourceMetadata,
+#if MAJOR_VERSION <= 6
+            AudioOutputFlags flags);
+#else
+            const AudioOutputFlags& flags);
+#endif
+    std::tuple<Result, sp<IStreamIn>, AudioConfig> openInputStreamImpl(
+            int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+#if MAJOR_VERSION <= 6
+            AudioInputFlags flags,
+#else
+            const AudioInputFlags& flags,
+#endif
+            const SinkMetadata& sinkMetadata);
+#endif  // MAJOR_VERSION >= 4
 
     Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                   const AudioConfig& config,
@@ -97,6 +118,17 @@
 #endif
                                  openInputStream_cb _hidl_cb) override;
 
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<void> openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                      const AudioConfig& config, const AudioOutputFlags& flags,
+                                      const SourceMetadata& sourceMetadata,
+                                      openOutputStream_7_1_cb _hidl_cb) override;
+    Return<void> openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                     const AudioConfig& config, const AudioInputFlags& flags,
+                                     const SinkMetadata& sinkMetadata,
+                                     openInputStream_7_1_cb _hidl_cb) override;
+#endif
+
     Return<bool> supportsAudioPatches() override;
     Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
                                   const hidl_vec<AudioPortConfig>& sinks,
diff --git a/audio/core/all-versions/default/include/core/default/DevicesFactory.h b/audio/core/all-versions/default/include/core/default/DevicesFactory.h
index 9f93a38..566bc8a 100644
--- a/audio/core/all-versions/default/include/core/default/DevicesFactory.h
+++ b/audio/core/all-versions/default/include/core/default/DevicesFactory.h
@@ -44,11 +44,17 @@
     Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
     Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
 #endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override;
+    Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override;
+#endif
 
-   private:
+  private:
     template <class DeviceShim, class Callback>
     Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
+#if MAJOR_VERSION == 2
     Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
+#endif
 
     static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
 };
diff --git a/audio/core/all-versions/default/include/core/default/ParametersUtil.h b/audio/core/all-versions/default/include/core/default/ParametersUtil.h
index 45d9b21..25c193a 100644
--- a/audio/core/all-versions/default/include/core/default/ParametersUtil.h
+++ b/audio/core/all-versions/default/include/core/default/ParametersUtil.h
@@ -17,7 +17,10 @@
 #ifndef ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_
 #define ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_
 
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+// clang-format on
 
 #include <functional>
 #include <memory>
@@ -28,13 +31,13 @@
 namespace android {
 namespace hardware {
 namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
 namespace implementation {
 
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
 class ParametersUtil {
    public:
@@ -62,7 +65,7 @@
 };
 
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace CORE_TYPES_CPP_VERSION
 }  // namespace audio
 }  // namespace hardware
 }  // namespace android
diff --git a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
index 5f65acf..8b37e01 100644
--- a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
+++ b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
@@ -36,7 +36,8 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
 struct PrimaryDevice : public IPrimaryDevice {
@@ -135,8 +136,10 @@
     Return<Result> setBtHfpVolume(float volume) override;
     Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override;
 #endif
-
-   private:
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<sp<::android::hardware::audio::V7_1::IDevice>> getDevice() override { return mDevice; }
+#endif
+  private:
     sp<Device> mDevice;
 
     virtual ~PrimaryDevice();
diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h
index 66d60e3..4e79884 100644
--- a/audio/core/all-versions/default/include/core/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/default/Stream.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_HARDWARE_AUDIO_STREAM_H
 #define ANDROID_HARDWARE_AUDIO_STREAM_H
 
-#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
+// clang-format off
+#include PATH(android/hardware/audio/COMMON_TYPES_FILE_VERSION/IStream.h)
+// clang-format on
 
 #include "ParametersUtil.h"
 
@@ -41,10 +43,13 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil;
 #if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+        AudioChannelBitfield;
 #endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
 struct Stream : public IStream, public ParametersUtil {
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index a980f3f..a6346e5 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -42,7 +42,8 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
 struct StreamIn : public IStreamIn {
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index 0b07972..ce5253f 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -43,7 +43,8 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
 struct StreamOut : public IStreamOut {
@@ -152,6 +153,12 @@
     Result doUpdateSourceMetadata(const SourceMetadata& sourceMetadata);
 #if MAJOR_VERSION >= 7
     Result doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<Result> setLatencyMode(LatencyMode mode) override;
+    Return<void> getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) override;
+    Return<Result> setLatencyModeCallback(
+            const sp<IStreamOutLatencyModeCallback>& callback) override;
+#endif
 #endif
 #endif  // MAJOR_VERSION >= 4
 
@@ -162,6 +169,9 @@
     mediautils::atomic_sp<IStreamOutCallback> mCallback;  // for non-blocking write and drain
 #if MAJOR_VERSION >= 6
     mediautils::atomic_sp<IStreamOutEventCallback> mEventCallback;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    mediautils::atomic_sp<IStreamOutLatencyModeCallback> mLatencyModeCallback;
+#endif
 #endif
     std::unique_ptr<CommandMQ> mCommandMQ;
     std::unique_ptr<DataMQ> mDataMQ;
@@ -176,6 +186,9 @@
 
 #if MAJOR_VERSION >= 6
     static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie);
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    static void latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie);
+#endif
 #endif
 };
 
diff --git a/audio/core/all-versions/default/include/core/default/Util.h b/audio/core/all-versions/default/include/core/default/Util.h
index 78ae03e..abf5317 100644
--- a/audio/core/all-versions/default/include/core/default/Util.h
+++ b/audio/core/all-versions/default/include/core/default/Util.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_HARDWARE_AUDIO_UTIL_H
 #define ANDROID_HARDWARE_AUDIO_UTIL_H
 
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+// clang-format on
 
 #include <algorithm>
 #include <vector>
@@ -27,19 +29,19 @@
 namespace android {
 namespace hardware {
 namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
 namespace implementation {
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+
+namespace util {
 
 /** @return true if gain is between 0 and 1 included. */
 constexpr bool isGainNormalized(float gain) {
     return gain >= 0.0 && gain <= 1.0;
 }
 
-namespace util {
-
 template <typename T>
 inline bool element_in(T e, const std::vector<T>& v) {
     return std::find(v.begin(), v.end(), e) != v.end();
@@ -72,7 +74,7 @@
 
 }  // namespace util
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace CORE_TYPES_CPP_VERSION
 }  // namespace audio
 }  // namespace hardware
 }  // namespace android
diff --git a/audio/core/all-versions/default/util/CoreUtils.cpp b/audio/core/all-versions/default/util/CoreUtils.cpp
index 773be21..8e83ea1 100644
--- a/audio/core/all-versions/default/util/CoreUtils.cpp
+++ b/audio/core/all-versions/default/util/CoreUtils.cpp
@@ -15,24 +15,24 @@
  */
 
 #if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
 #endif
 #include <HidlUtils.h>
 #include <log/log.h>
 
 #include "util/CoreUtils.h"
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 #if MAJOR_VERSION >= 7
 namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
 }
 #endif
 
 namespace android {
 namespace hardware {
 namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
 namespace implementation {
 
 #define CONVERT_CHECKED(expr, result)                   \
@@ -389,7 +389,7 @@
 
 #if MAJOR_VERSION >= 7
 namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
 }
 
 status_t CoreUtils::audioInputFlagsFromHal(audio_input_flags_t halFlagMask,
@@ -470,7 +470,7 @@
 #endif
 
 }  // namespace implementation
-}  // namespace CPP_VERSION
+}  // namespace CORE_TYPES_CPP_VERSION
 }  // namespace audio
 }  // namespace hardware
 }  // namespace android
diff --git a/audio/core/all-versions/default/util/include/util/CoreUtils.h b/audio/core/all-versions/default/util/include/util/CoreUtils.h
index 1e5272a..dc35772 100644
--- a/audio/core/all-versions/default/util/include/util/CoreUtils.h
+++ b/audio/core/all-versions/default/util/include/util/CoreUtils.h
@@ -17,7 +17,7 @@
 #pragma once
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
 // clang-format off
 
 #include <vector>
@@ -30,13 +30,13 @@
 namespace android {
 namespace hardware {
 namespace audio {
-namespace CPP_VERSION {
+namespace CORE_TYPES_CPP_VERSION {
 namespace implementation {
 
 using ::android::hardware::audio::common::utils::EnumBitfield;
 using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
 struct CoreUtils {
     // Note: the converters for DeviceAddress have to be in CoreUtils for HAL V4
@@ -93,8 +93,8 @@
         return NO_ERROR;
     }
 #else
-    using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
-    using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
+    using AudioInputFlags = hidl_vec<::android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>;
+    using AudioOutputFlags = hidl_vec<::android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>;
     static status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags);
     static status_t audioInputFlagsToHal(const AudioInputFlags& flags, audio_input_flags_t* halFlagMask);
     static status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags);
diff --git a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
index 0c18482..3976b08 100644
--- a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
+++ b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
@@ -28,7 +28,7 @@
 #include <xsdc/XsdcSupport.h>
 
 using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
diff --git a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
index 1cffd41..dd80dd6 100644
--- a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalUtils.h
@@ -14,16 +14,18 @@
  * limitations under the License.
  */
 
+// clang-format off
 #include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
 #include <hidl/HidlSupport.h>
 
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
-using ::android::hardware::audio::common::CPP_VERSION::AudioChannelMask;
-using ::android::hardware::audio::common::CPP_VERSION::AudioFormat;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioChannelMask;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioFormat;
 using ::android::hardware::audio::CPP_VERSION::IStream;
 using ::android::hardware::audio::CPP_VERSION::ParameterValue;
 using ::android::hardware::audio::CPP_VERSION::Result;
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 787654b..a9797bb 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -17,7 +17,7 @@
 #include "AudioPrimaryHidlHalTest.h"
 
 #if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_H_FILENAME)
 #include <xsdc/XsdcSupport.h>
 
 using android::xsdc_enum_range;
@@ -28,17 +28,37 @@
     if (getDeviceName() != DeviceManager::kPrimaryDevice) {
         GTEST_SKIP() << "No primary device on this factory";  // returns
     }
-
-    {  // Scope for device SPs
-        sp<IDevice> baseDevice =
-                DeviceManager::getInstance().get(getFactoryName(), DeviceManager::kPrimaryDevice);
-        ASSERT_TRUE(baseDevice != nullptr);
-        Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
-        EXPECT_TRUE(primaryDevice.isOk());
-        EXPECT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
-    }
     EXPECT_TRUE(
             DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice));
+
+    // Must use IDevicesFactory directly because DeviceManager always uses
+    // the latest interfaces version and corresponding methods for opening
+    // them. However, in minor package uprevs IPrimaryDevice does not inherit
+    // IDevice from the same package and thus IDevice can not be upcasted
+    // (see the interfaces in V7.1).
+    auto factory = DevicesFactoryManager::getInstance().get(getFactoryName());
+    ASSERT_TRUE(factory != nullptr);
+    sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IDevice> baseDevice;
+    Result result;
+    auto ret = factory->openDevice(DeviceManager::kPrimaryDevice, returnIn(result, baseDevice));
+    ASSERT_TRUE(ret.isOk()) << ret.description();
+    ASSERT_EQ(Result::OK, result);
+    ASSERT_TRUE(baseDevice != nullptr);
+    {
+        Return<sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice>>
+                primaryDevice = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice::
+                        castFrom(baseDevice);
+        EXPECT_TRUE(primaryDevice.isOk());
+        EXPECT_TRUE(sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice>(
+                            primaryDevice) != nullptr);
+    }
+#if MAJOR_VERSION < 6
+    baseDevice.clear();
+    DeviceManager::waitForInstanceDestruction();
+#else
+    auto closeRet = baseDevice->close();
+    EXPECT_TRUE(closeRet.isOk());
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -183,7 +203,7 @@
                areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
                                           : testSetDevices(stream.get(), address))
 
-static void checkGetHwAVSync(IDevice* device) {
+static void checkGetHwAVSync(::android::hardware::audio::CPP_VERSION::IDevice* device) {
     Result res;
     AudioHwSync sync;
     ASSERT_OK(device->getHwAvSync(returnIn(res, sync)));
@@ -215,7 +235,7 @@
     ASSERT_OK(stream->updateSinkMetadata(initMetadata));
 
 #elif MAJOR_VERSION >= 7
-    xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioSource> range;
+    xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioSource> range;
     // Test all possible track configuration
     for (auto source : range) {
         for (float volume : {0.0, 0.5, 1.0}) {
@@ -272,8 +292,9 @@
     // Restore initial
     ASSERT_OK(stream->updateSourceMetadata(initMetadata));
 #elif MAJOR_VERSION >= 7
-    xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioUsage> usageRange;
-    xsdc_enum_range<android::audio::policy::configuration::V7_0::AudioContentType> contentRange;
+    xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioUsage> usageRange;
+    xsdc_enum_range<android::audio::policy::configuration::CPP_VERSION::AudioContentType>
+            contentRange;
     // Test all possible track configuration
     for (auto usage : usageRange) {
         for (auto content : contentRange) {
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
index 81a1f7b..a567cf9 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
@@ -14,33 +14,36 @@
  * limitations under the License.
  */
 
-#include PATH(android/hardware/audio/FILE_VERSION/IStream.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamIn.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
+// clang-format on
 #include <hidl/HidlSupport.h>
 
 using ::android::hardware::hidl_bitfield;
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
-using ::android::hardware::audio::common::CPP_VERSION::AudioChannelMask;
-using ::android::hardware::audio::common::CPP_VERSION::AudioFormat;
-using ::android::hardware::audio::CPP_VERSION::IStream;
-using ::android::hardware::audio::CPP_VERSION::ParameterValue;
-using ::android::hardware::audio::CPP_VERSION::Result;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioChannelMask;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioFormat;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStream;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::ParameterValue;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::Result;
 
 using namespace ::android::hardware::audio::common::test::utility;
 
-using Rotation = ::android::hardware::audio::CPP_VERSION::IPrimaryDevice::Rotation;
-using ::android::hardware::audio::common::CPP_VERSION::AudioContentType;
-using ::android::hardware::audio::common::CPP_VERSION::AudioUsage;
-using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
+using Rotation = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IPrimaryDevice::Rotation;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioContentType;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioUsage;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::MicrophoneInfo;
 #if MAJOR_VERSION < 5
 using ::android::hardware::audio::CPP_VERSION::SinkMetadata;
 using ::android::hardware::audio::CPP_VERSION::SourceMetadata;
 #else
-using ::android::hardware::audio::common::CPP_VERSION::SinkMetadata;
-using ::android::hardware::audio::common::CPP_VERSION::SourceMetadata;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::SinkMetadata;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::SourceMetadata;
 #endif
 
 struct Parameters {
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 8af4c78..aef94da 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -59,7 +59,8 @@
     testAccessors<OPTIONAL>(&OutputStreamTest::getStream, "dual mono mode",
                             Initial{DualMonoMode::OFF},
                             {DualMonoMode::LR, DualMonoMode::LL, DualMonoMode::RR},
-                            &IStreamOut::setDualMonoMode, &IStreamOut::getDualMonoMode);
+                            &::android::hardware::audio::CPP_VERSION::IStreamOut::setDualMonoMode,
+                            &::android::hardware::audio::CPP_VERSION::IStreamOut::getDualMonoMode);
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DualMonoModeAccessorHidlTest);
@@ -73,7 +74,8 @@
     testAccessors<OPTIONAL>(
             &OutputStreamTest::getStream, "audio description mix level",
             Initial{-std::numeric_limits<float>::infinity()}, {-48.0f, -1.0f, 0.0f, 1.0f, 48.0f},
-            &IStreamOut::setAudioDescriptionMixLevel, &IStreamOut::getAudioDescriptionMixLevel,
+            &::android::hardware::audio::CPP_VERSION::IStreamOut::setAudioDescriptionMixLevel,
+            &::android::hardware::audio::CPP_VERSION::IStreamOut::getAudioDescriptionMixLevel,
             {48.5f, 1000.0f, std::numeric_limits<float>::infinity()});
 }
 
@@ -105,7 +107,8 @@
              PlaybackRate{0.5f, 0.5f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
              PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
              PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::FAIL}},
-            &IStreamOut::setPlaybackRateParameters, &IStreamOut::getPlaybackRateParameters,
+            &::android::hardware::audio::CPP_VERSION::IStreamOut::setPlaybackRateParameters,
+            &::android::hardware::audio::CPP_VERSION::IStreamOut::getPlaybackRateParameters,
             {PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
                           TimestretchFallbackMode::FAIL},
              PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE,
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
index e3b98c9..dafd326 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -21,8 +21,8 @@
 #include "PolicyConfig.h"
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
 // Forward declaration for functions that are substituted
@@ -30,7 +30,7 @@
 const PolicyConfig& getCachedPolicyConfig();
 const std::vector<DeviceParameter>& getDeviceParameters();
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
 std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 222fad7..f25c391 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -381,13 +381,13 @@
             "IDevice::open{Input|Output}Stream method.");
     AudioConfig suggestedConfig{};
     if (isParamForInputStream()) {
-        sp<IStreamIn> stream;
+        sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> stream;
         ASSERT_OK(getDevice()->openInputStream(AudioIoHandle{}, getDeviceAddress(), getConfig(),
                                                getFlags(), getSinkMetadata(),
                                                returnIn(res, stream, suggestedConfig)));
         ASSERT_TRUE(stream == nullptr);
     } else {
-        sp<IStreamOut> stream;
+        sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamOut> stream;
         ASSERT_OK(getDevice()->openOutputStream(AudioIoHandle{}, getDeviceAddress(), getConfig(),
                                                 getFlags(), getSourceMetadata(),
                                                 returnIn(res, stream, suggestedConfig)));
@@ -551,13 +551,15 @@
     }
 
     void releasePatchIfNeeded() {
-        if (areAudioPatchesSupported()) {
-            if (mHasPatch) {
+        if (getDevice()) {
+            if (areAudioPatchesSupported() && mHasPatch) {
                 EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
                 mHasPatch = false;
             }
         } else {
-            EXPECT_OK(stream->setDevices({address}));
+            if (stream) {
+                EXPECT_OK(stream->setDevices({address}));
+            }
         }
     }
 
@@ -724,13 +726,15 @@
     }
 
     void releasePatchIfNeeded() {
-        if (areAudioPatchesSupported()) {
-            if (mHasPatch) {
+        if (getDevice()) {
+            if (areAudioPatchesSupported() && mHasPatch) {
                 EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
                 mHasPatch = false;
             }
         } else {
-            EXPECT_OK(stream->setDevices({address}));
+            if (stream) {
+                EXPECT_OK(stream->setDevices({address}));
+            }
         }
     }
 
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
index 42bf1d3..f936d0a 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -20,20 +20,20 @@
 #include "7.0/PolicyConfig.h"
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
 
 // Forward declaration for functions that are substituted
 // in generator unit tests.
 const PolicyConfig& getCachedPolicyConfig();
 const std::vector<DeviceParameter>& getDeviceParameters();
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 namespace xsd {
 using namespace ::android::audio::policy::configuration::CPP_VERSION;
 }
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
index 2988207..d674403 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.cpp
@@ -30,9 +30,9 @@
 using ::android::NO_ERROR;
 using ::android::OK;
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 using ::android::hardware::audio::common::utils::splitString;
 namespace xsd {
 using namespace ::android::audio::policy::configuration::CPP_VERSION;
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index f798839..4aea503 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -25,15 +25,15 @@
 #include <utils/Errors.h>
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 namespace xsd {
 using namespace ::android::audio::policy::configuration::CPP_VERSION;
 using Module = Modules::Module;
diff --git a/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
new file mode 100644
index 0000000..b750f56
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// pull in all the <= 7.0 tests
+#include "7.0/AudioPrimaryHidlHalTest.cpp"
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index cfee26a..d810c55 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -179,6 +179,39 @@
     test_config: "VtsHalAudioV7_0TargetTest.xml",
 }
 
+cc_test {
+    name: "VtsHalAudioV7_1TargetTest",
+    defaults: ["VtsHalAudioTargetTest_defaults"],
+    srcs: [
+        "7.1/AudioPrimaryHidlHalTest.cpp",
+        "7.0/Generators.cpp",
+        "7.0/PolicyConfig.cpp",
+    ],
+    generated_headers: ["audio_policy_configuration_V7_1_parser"],
+    generated_sources: ["audio_policy_configuration_V7_1_parser"],
+    static_libs: [
+        "android.hardware.audio@7.0",
+        "android.hardware.audio@7.1",
+        "android.hardware.audio.common@7.0",
+        "android.hardware.audio.common@7.0-enums",
+        "android.hardware.audio.common@7.1-enums",
+        "android.hardware.audio.common@7.0-util",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=7",
+        "-DMINOR_VERSION=1",
+        "-DCOMMON_TYPES_MINOR_VERSION=0",
+        "-DCORE_TYPES_MINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ],
+    data: [
+        ":audio_policy_configuration_V7_1",
+    ],
+    // Use test_config for vts suite.
+    // TODO(b/146104851): Add auto-gen rules and remove it.
+    test_config: "VtsHalAudioV7_1TargetTest.xml",
+}
+
 // Note: the following aren't VTS tests, but rather unit tests
 // to verify correctness of test utilities.
 cc_test {
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 340903a..404532a 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -37,15 +37,17 @@
 #include <android-base/logging.h>
 #include <system/audio_config.h>
 
+// clang-format off
 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
 #include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 #if MAJOR_VERSION >= 7
-#include <android_audio_policy_configuration_V7_0-enums.h>
-#include <android_audio_policy_configuration_V7_0.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
+#include PATH(APM_XSD_H_FILENAME)
 #endif
+// clang-format on
 
 #include <fmq/EventFlag.h>
 #include <fmq/MessageQueue.h>
@@ -86,7 +88,7 @@
 using ::android::hardware::audio::common::utils::mkEnumBitfield;
 using ::android::hardware::details::toHexString;
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::common::test::utility;
 using namespace ::android::hardware::audio::CPP_VERSION;
 using ReadParameters = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadParameters;
@@ -124,6 +126,9 @@
 
 class HidlTest : public ::testing::Test {
   public:
+    using IDevice = ::android::hardware::audio::CPP_VERSION::IDevice;
+    using IDevicesFactory = ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+
     virtual ~HidlTest() = default;
     // public access to avoid annoyances when using this method in template classes
     // derived from test classes
@@ -168,7 +173,8 @@
 }
 
 TEST(CheckConfig, audioPolicyConfigurationValidation) {
-    const auto factories = ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+    const auto factories = ::android::hardware::getAllHalInstanceNames(
+            ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
     if (factories.size() == 0) {
         GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
                         "are found.";
@@ -198,8 +204,8 @@
 const std::vector<DeviceParameter>& getDeviceParameters() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories =
-                ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+        const auto factories = ::android::hardware::getAllHalInstanceNames(
+                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
         const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
         result.reserve(devices.size());
         for (const auto& factoryName : factories) {
@@ -217,8 +223,8 @@
 const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories =
-                ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+        const auto factories = ::android::hardware::getAllHalInstanceNames(
+                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
         for (const auto& factoryName : factories) {
             result.emplace_back(factoryName,
                                 DeviceManager::getInstance().getPrimary(factoryName) != nullptr
@@ -288,6 +294,8 @@
 // Test audio devices factory
 class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
   public:
+    using IPrimaryDevice = ::android::hardware::audio::CPP_VERSION::IPrimaryDevice;
+
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp());  // setup base
         ASSERT_TRUE(getDevicesFactory() != nullptr);
@@ -301,7 +309,7 @@
 TEST_P(AudioHidlTest, OpenDeviceInvalidParameter) {
     doc::test("Test passing an invalid parameter to openDevice");
     Result result;
-    sp<IDevice> device;
+    sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IDevice> device;
 #if MAJOR_VERSION == 2
     auto invalidDevice = IDevicesFactory::Device(-1);
 #elif MAJOR_VERSION >= 4
@@ -572,8 +580,8 @@
                     [](auto&& arg) -> std::string {
                         using T = std::decay_t<decltype(arg)>;
                         // Need to use FQN of toString to avoid confusing the compiler
-                        return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
-                                hidl_bitfield<T>(arg));
+                        return ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::
+                                toString<T>(hidl_bitfield<T>(arg));
                     },
                     std::get<PARAM_FLAGS>(info.param)));
 #elif MAJOR_VERSION >= 7
@@ -890,6 +898,8 @@
 
 class StreamWriter : public StreamWorker<StreamWriter> {
   public:
+    using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
+
     StreamWriter(IStreamOut* stream, size_t bufferSize)
         : mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
     ~StreamWriter() {
@@ -998,7 +1008,8 @@
     EventFlag* mEfGroup = nullptr;
 };
 
-class OutputStreamTest : public OpenStreamTest<IStreamOut> {
+class OutputStreamTest
+    : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamOut> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
 #if MAJOR_VERSION <= 6
@@ -1012,9 +1023,12 @@
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
 #if MAJOR_VERSION == 2
                     return getDevice()->openOutputStream(handle, address, config, flags, cb);
-#elif MAJOR_VERSION >= 4
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
                     return getDevice()->openOutputStream(handle, address, config, flags,
                                                          initMetadata, cb);
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+                    return getDevice()->openOutputStream_7_1(handle, address, config, flags,
+                                                             initMetadata, cb);
 #endif
                 },
                 config);
@@ -1075,6 +1089,8 @@
 
 class StreamReader : public StreamWorker<StreamReader> {
   public:
+    using IStreamIn = ::android::hardware::audio::CPP_VERSION::IStreamIn;
+
     StreamReader(IStreamIn* stream, size_t bufferSize)
         : mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
     ~StreamReader() {
@@ -1188,7 +1204,7 @@
     EventFlag* mEfGroup = nullptr;
 };
 
-class InputStreamTest : public OpenStreamTest<IStreamIn> {
+class InputStreamTest : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamIn> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
 #if MAJOR_VERSION <= 6
@@ -1210,8 +1226,13 @@
         auto flags = getInputFlags();
         testOpen(
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+#if MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
                     return getDevice()->openInputStream(handle, address, config, flags,
                                                         initMetadata, cb);
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+                    return getDevice()->openInputStream_7_1(handle, address, config, flags,
+                                                            initMetadata, cb);
+#endif
                 },
                 config);
     }
@@ -1584,7 +1605,8 @@
                             "InputStream::setGain");
 }
 
-static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForReading(::android::hardware::audio::CPP_VERSION::IStreamIn* stream,
+                                  uint32_t frameSize, uint32_t framesCount) {
     Result res;
     // Ignore output parameters as the call should fail
     ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
@@ -1655,7 +1677,8 @@
                             "setVolume");
 }
 
-static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForWriting(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
+                                  uint32_t frameSize, uint32_t framesCount) {
     Result res;
     // Ignore output parameters as the call should fail
     ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
@@ -1682,6 +1705,8 @@
 }
 
 struct Capability {
+    using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
+
     Capability(IStreamOut* stream) {
         EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
         drain = extract(stream->supportsDrain());
@@ -1725,7 +1750,7 @@
     Return<void> onError() override { return {}; }
 };
 
-static bool isAsyncModeSupported(IStreamOut* stream) {
+static bool isAsyncModeSupported(::android::hardware::audio::CPP_VERSION::IStreamOut* stream) {
     auto res = stream->setCallback(new MockOutCallbacks);
     stream->clearCallback();  // try to restore the no callback state, ignore
                               // any error
@@ -1780,7 +1805,8 @@
     ASSERT_RESULT(Result::INVALID_STATE, stream->pause());
 }
 
-static void testDrain(IStreamOut* stream, AudioDrain type) {
+static void testDrain(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
+                      AudioDrain type) {
     if (!Capability(stream).drain) {
         doc::partialTest("The output stream does not support drain");
         return;
@@ -1866,7 +1892,8 @@
 }
 
 using TtyModeAccessorPrimaryHidlTest =
-        AccessorHidlTest<IPrimaryDevice::TtyMode, AudioPrimaryHidlTest>;
+        AccessorHidlTest<::android::hardware::audio::CPP_VERSION::IPrimaryDevice::TtyMode,
+                         AudioPrimaryHidlTest>;
 TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
     doc::test("Query and set the TTY mode state");
     testAccessors<OPTIONAL>(
diff --git a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
index aa67630..802b87b 100644
--- a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
+++ b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
@@ -22,8 +22,8 @@
 #include <vector>
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
 enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
@@ -34,14 +34,14 @@
 #if MAJOR_VERSION <= 6
 enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
 enum { INDEX_INPUT, INDEX_OUTPUT };
-using DeviceConfigParameter =
-        std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
-                   std::variant<android::hardware::audio::common::CPP_VERSION::AudioInputFlag,
-                                android::hardware::audio::common::CPP_VERSION::AudioOutputFlag>>;
+using DeviceConfigParameter = std::tuple<
+        DeviceParameter, android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
+        std::variant<android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioInputFlag,
+                     android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioOutputFlag>>;
 #elif MAJOR_VERSION >= 7
 enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_CONFIG, PARAM_FLAGS };
 using DeviceConfigParameter =
         std::tuple<DeviceParameter, std::string,
-                   android::hardware::audio::common::CPP_VERSION::AudioConfig,
-                   std::vector<android::hardware::audio::CPP_VERSION::AudioInOutFlag>>;
+                   android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
+                   std::vector<android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>>;
 #endif
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index a2bb1ee..e4008cf 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -21,8 +21,8 @@
 #include "PolicyConfig.h"
 
 // clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
 using ::android::hardware::audio::common::utils::EnumBitfield;
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index 6db78a7..c8e0167 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -22,19 +22,21 @@
 
 #include <android-base/logging.h>
 #include <hwbinder/IPCThreadState.h>
+#include <system/audio.h>
 
 // clang-format off
 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
 #include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
-#include PATH(android/hardware/audio/FILE_VERSION/types.h)
-#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
 // clang-format on
 
 #include "utility/ReturnIn.h"
 
 using ::android::sp;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::Result;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::common::test::utility;
 using namespace ::android::hardware::audio::CPP_VERSION;
 
@@ -104,21 +106,30 @@
     static sp<IDevice> createInterfaceInstance(const FactoryAndDevice& factoryAndDevice) {
         auto [factoryName, name] = factoryAndDevice;
         sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
-        return name == kPrimaryDevice ? openPrimaryDevice(factory) : openDevice(factory, name);
+        return openDevice(factory, name);
     }
     using InterfaceManager::reset;
 
     static constexpr const char* kPrimaryDevice = "primary";
 
     sp<IDevice> get(const std::string& factoryName, const std::string& name) {
+        if (name == kPrimaryDevice) {
+            (void)getPrimary(factoryName);  // for initializing primaryDevice if needed.
+        }
         return InterfaceManager::get(std::make_tuple(factoryName, name));
     }
     sp<IPrimaryDevice> getPrimary(const std::string& factoryName) {
-        sp<IDevice> device = get(factoryName, kPrimaryDevice);
-        return device != nullptr ? IPrimaryDevice::castFrom(device) : nullptr;
+        if (primaryDevice == nullptr) {
+            sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
+            primaryDevice = openPrimaryDevice(factory);
+        }
+        return primaryDevice;
     }
     bool reset(const std::string& factoryName, const std::string& name)
             __attribute__((warn_unused_result)) {
+        if (name == kPrimaryDevice) {
+            primaryDevice.clear();
+        }
 #if MAJOR_VERSION <= 5
         return InterfaceManager::reset(std::make_tuple(factoryName, name), true);
 #elif MAJOR_VERSION >= 6
@@ -140,35 +151,75 @@
   private:
     static sp<IDevice> openDevice(const sp<IDevicesFactory>& factory, const std::string& name) {
         if (factory == nullptr) return nullptr;
-        sp<IDevice> device;
-#if MAJOR_VERSION >= 4
         Result result;
+        sp<IDevice> device;
+#if MAJOR_VERSION == 2
+        IDevicesFactory::Device dev = IDevicesFactory::IDevicesFactory::Device(-1);
+        if (name == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+            dev = IDevicesFactory::Device::PRIMARY;
+        } else if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) {
+            dev = IDevicesFactory::Device::A2DP;
+        } else if (name == AUDIO_HARDWARE_MODULE_ID_USB) {
+            dev = IDevicesFactory::Device::USB;
+        } else if (name == AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) {
+            dev = IDevicesFactory::Device::R_SUBMIX;
+        } else if (name == AUDIO_HARDWARE_MODULE_ID_STUB) {
+            dev = IDevicesFactory::Device::STUB;
+        }
+        auto ret = factory->openDevice(dev, returnIn(result, device));
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
         auto ret = factory->openDevice(name, returnIn(result, device));
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+        auto ret = factory->openDevice_7_1(name, returnIn(result, device));
+#endif
         if (!ret.isOk() || result != Result::OK || device == nullptr) {
             ALOGW("Device %s can not be opened, transaction: %s, result %d, device %p",
                   name.c_str(), ret.description().c_str(), result, device.get());
             return nullptr;
         }
-#else
-        (void)name;
-#endif
         return device;
     }
 
-    static sp<IDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
-        if (factory == nullptr) return nullptr;
+    static sp<IPrimaryDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
+        if (factory == nullptr) return {};
         Result result;
         sp<IDevice> device;
+        sp<IPrimaryDevice> primaryDevice;
 #if MAJOR_VERSION == 2
         auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device));
-#elif MAJOR_VERSION >= 4
+        if (ret.isOk() && result == Result::OK && device != nullptr) {
+            primaryDevice = IPrimaryDevice::castFrom(device);
+        }
+#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
         auto ret = factory->openPrimaryDevice(returnIn(result, device));
+        if (ret.isOk() && result == Result::OK && device != nullptr) {
+            primaryDevice = IPrimaryDevice::castFrom(device);
+        }
+#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
+        auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice));
+        if (ret.isOk() && result == Result::OK && primaryDevice != nullptr) {
+            auto getDeviceRet = primaryDevice->getDevice();
+            if (getDeviceRet.isOk()) {
+                device = getDeviceRet;
+            } else {
+                primaryDevice.clear();
+                ALOGW("Primary device can not downcast, transaction: %s, primary %p",
+                      getDeviceRet.description().c_str(), primaryDevice.get());
+                return {};
+            }
+        }
 #endif
         if (!ret.isOk() || result != Result::OK || device == nullptr) {
             ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p",
                   ret.description().c_str(), result, device.get());
-            return nullptr;
+            return {};
         }
-        return device;
+        return primaryDevice;
     }
+
+  private:
+    // There can only be one primary device across all HAL modules.
+    // A reference to a complete interface is used because in V7.1 IDevice can not
+    // be upcasted to IPrimaryDevice.
+    sp<IPrimaryDevice> primaryDevice;
 };
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
new file mode 100644
index 0000000..7b33a8f
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<configuration description="Runs VtsHalAudioV7_1TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="setprop vts.native_server.on 1"/>
+        <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalAudioV7_1TargetTest->/data/local/tmp/VtsHalAudioV7_1TargetTest" />
+        <option name="push" value="audio_policy_configuration_V7_1.xsd->/data/local/tmp/audio_policy_configuration_V7_1.xsd" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalAudioV7_1TargetTest" />
+        <option name="native-test-timeout" value="5m" />
+    </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
index 3fdd8e6..76bf93e 100644
--- a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -33,7 +33,7 @@
 #endif
 
 using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 #if MAJOR_VERSION == 7
 namespace xsd {
 using namespace ::android::audio::policy::configuration::CPP_VERSION;
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index ccfc6b2..49f6bf2 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -42,9 +42,10 @@
 namespace implementation {
 
 #if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+        AudioChannelBitfield;
 #endif
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 
 namespace {
 
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index d5218f7..f9a6796 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -48,9 +48,10 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 #if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioDeviceBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+        AudioDeviceBitfield;
 #endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct Effect : public IEffect {
diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp
index eb1cb49..e93ad89 100644
--- a/audio/effect/all-versions/default/EffectsFactory.cpp
+++ b/audio/effect/all-versions/default/EffectsFactory.cpp
@@ -53,7 +53,7 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::UuidUtils;
 
 // static
 sp<IEffect> EffectsFactory::dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor,
diff --git a/audio/effect/all-versions/default/EffectsFactory.h b/audio/effect/all-versions/default/EffectsFactory.h
index 0b86836..da16923 100644
--- a/audio/effect/all-versions/default/EffectsFactory.h
+++ b/audio/effect/all-versions/default/EffectsFactory.h
@@ -41,7 +41,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct EffectsFactory : public IEffectsFactory {
diff --git a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
index 9694b5d..001774d 100644
--- a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
+++ b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h
@@ -43,7 +43,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect {
diff --git a/audio/effect/all-versions/default/EqualizerEffect.h b/audio/effect/all-versions/default/EqualizerEffect.h
index 7a6bc0a..c4d76c1 100644
--- a/audio/effect/all-versions/default/EqualizerEffect.h
+++ b/audio/effect/all-versions/default/EqualizerEffect.h
@@ -43,7 +43,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct EqualizerEffect : public IEqualizerEffect {
diff --git a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
index 6d80207..122ec36 100644
--- a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
+++ b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h
@@ -39,7 +39,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect {
diff --git a/audio/effect/all-versions/default/NoiseSuppressionEffect.h b/audio/effect/all-versions/default/NoiseSuppressionEffect.h
index 6cc45b9..96b9ecf 100644
--- a/audio/effect/all-versions/default/NoiseSuppressionEffect.h
+++ b/audio/effect/all-versions/default/NoiseSuppressionEffect.h
@@ -41,7 +41,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct NoiseSuppressionEffect : public INoiseSuppressionEffect {
diff --git a/audio/effect/all-versions/default/PresetReverbEffect.h b/audio/effect/all-versions/default/PresetReverbEffect.h
index eb55e20..9d82c08 100644
--- a/audio/effect/all-versions/default/PresetReverbEffect.h
+++ b/audio/effect/all-versions/default/PresetReverbEffect.h
@@ -39,7 +39,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct PresetReverbEffect : public IPresetReverbEffect {
diff --git a/audio/effect/all-versions/default/VirtualizerEffect.cpp b/audio/effect/all-versions/default/VirtualizerEffect.cpp
index 1dce181..6efc4ea 100644
--- a/audio/effect/all-versions/default/VirtualizerEffect.cpp
+++ b/audio/effect/all-versions/default/VirtualizerEffect.cpp
@@ -34,7 +34,7 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
 
 VirtualizerEffect::VirtualizerEffect(effect_handle_t handle)
     : mEffect(new Effect(false /*isInput*/, handle)) {}
diff --git a/audio/effect/all-versions/default/VirtualizerEffect.h b/audio/effect/all-versions/default/VirtualizerEffect.h
index 3ed06d1..f26e4fa 100644
--- a/audio/effect/all-versions/default/VirtualizerEffect.h
+++ b/audio/effect/all-versions/default/VirtualizerEffect.h
@@ -40,9 +40,10 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 #if MAJOR_VERSION <= 6
-using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::
+        AudioChannelBitfield;
 #endif
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct VirtualizerEffect : public IVirtualizerEffect {
diff --git a/audio/effect/all-versions/default/VisualizerEffect.h b/audio/effect/all-versions/default/VisualizerEffect.h
index 3ae4b08..b8424c4 100644
--- a/audio/effect/all-versions/default/VisualizerEffect.h
+++ b/audio/effect/all-versions/default/VisualizerEffect.h
@@ -39,7 +39,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
 struct VisualizerEffect : public IVisualizerEffect {
diff --git a/audio/effect/all-versions/default/util/EffectUtils.cpp b/audio/effect/all-versions/default/util/EffectUtils.cpp
index 1156d21..296f84d 100644
--- a/audio/effect/all-versions/default/util/EffectUtils.cpp
+++ b/audio/effect/all-versions/default/util/EffectUtils.cpp
@@ -25,8 +25,8 @@
 
 #include "util/EffectUtils.h"
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
-using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::UuidUtils;
 using ::android::hardware::audio::common::utils::EnumBitfield;
 
 namespace android {
@@ -36,7 +36,7 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 
 #define CONVERT_CHECKED(expr, result)                   \
     if (status_t status = (expr); status != NO_ERROR) { \
diff --git a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
index d021fa0..adfa167 100644
--- a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
+++ b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp
@@ -27,7 +27,7 @@
 #include <xsdc/XsdcSupport.h>
 
 using namespace android;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
 namespace xsd {
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 23e7786..e59423f 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -50,7 +50,7 @@
 using ::android::hardware::audio::common::utils::mkEnumBitfield;
 using ::android::hidl::allocator::V1_0::IAllocator;
 using ::android::hidl::memory::V1_0::IMemory;
-using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 #if MAJOR_VERSION >= 7
 // Make an alias for enumerations generated from the APM config XSD.
diff --git a/bluetooth/audio/2.0/vts/OWNERS b/bluetooth/audio/2.0/vts/OWNERS
deleted file mode 100644
index b266b06..0000000
--- a/bluetooth/audio/2.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
diff --git a/bluetooth/audio/2.1/vts/OWNERS b/bluetooth/audio/2.1/vts/OWNERS
deleted file mode 100644
index b266b06..0000000
--- a/bluetooth/audio/2.1/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index f577537..7c91805 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -69,4 +69,12 @@
      *    encoding.
      */
     updateAudioConfiguration(AudioConfiguration audioConfig);
+
+    /**
+     * Called when the supported latency mode is updated.
+     *
+     * @param allowed If the peripheral devices can't keep up with low latency
+     * mode, the API will be called with supported is false.
+     */
+    setLowLatencyModeAllowed(bool allowed);
 };
diff --git a/bluetooth/audio/2.2/OWNERS b/bluetooth/audio/2.2/OWNERS
new file mode 100644
index 0000000..84f5b1e
--- /dev/null
+++ b/bluetooth/audio/2.2/OWNERS
@@ -0,0 +1,3 @@
+aliceypkuo@google.com
+ugoyu@google.com
+sattiraju@google.com
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 202cfb9..62511e9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -209,6 +209,18 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvider::setLowLatencyModeAllowed(bool allowed) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+  if (stack_iface_ == nullptr) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO session";
+    return Void();
+  }
+  LOG(INFO) << __func__ << " allowed: " << allowed;
+  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 425ea3b..90c158e 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -56,6 +56,8 @@
   Return<void> updateAudioConfiguration(
       const AudioConfiguration& audioConfig) override;
 
+  Return<void> setLowLatencyModeAllowed(bool allowed) override;
+
  protected:
   sp<BluetoothAudioDeathRecipient> death_recipient_;
 
diff --git a/bluetooth/audio/aidl/default/OWNERS b/bluetooth/audio/OWNERS
similarity index 98%
rename from bluetooth/audio/aidl/default/OWNERS
rename to bluetooth/audio/OWNERS
index 17ea464..a8e9bda 100644
--- a/bluetooth/audio/aidl/default/OWNERS
+++ b/bluetooth/audio/OWNERS
@@ -1,4 +1,4 @@
 include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
+aliceypkuo@google.com
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 5107240..52671b8 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -47,6 +47,7 @@
                 "//apex_available:platform",
                 "com.android.bluetooth",
             ],
+            min_sdk_version: "31",
         },
     },
 }
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
index 9a1557a..cc3c641 100644
--- 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
@@ -40,4 +40,6 @@
   void suspendStream();
   void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
   void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+  void setLatencyMode(in android.hardware.bluetooth.audio.LatencyMode latencyMode);
+  void setCodecType(in android.hardware.bluetooth.audio.CodecType codecType);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
similarity index 88%
rename from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
index 4f29c0b..5583679 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,10 @@
 // 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;
-@VintfStability
-parcelable NeighboringCell {
-  String cid;
-  int rssi;
+package android.hardware.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum LatencyMode {
+  UNKNOWN = 0,
+  LOW_LATENCY = 1,
+  FREE = 2,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 827f57d..81c2ce2 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -18,6 +18,8 @@
 
 import android.hardware.audio.common.SinkMetadata;
 import android.hardware.audio.common.SourceMetadata;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LatencyMode;
 import android.hardware.bluetooth.audio.PresentationPosition;
 
 /**
@@ -78,4 +80,18 @@
      * @param sinkMetadata as passed from Audio Framework
      */
     void updateSinkMetadata(in SinkMetadata sinkMetadata);
+
+    /**
+     * Called when latency mode is changed.
+     *
+     * @param latencyMode latency mode from audio
+     */
+    void setLatencyMode(in LatencyMode latencyMode);
+
+    /**
+     * Called when codec type is changed.
+     *
+     * @param codecType codec type from audio
+     */
+    void setCodecType(in CodecType codecType);
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
new file mode 100644
index 0000000..0c354f7
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum LatencyMode {
+    UNKNOWN,
+    LOW_LATENCY,
+    FREE,
+}
diff --git a/bluetooth/audio/aidl/vts/OWNERS b/bluetooth/audio/aidl/vts/OWNERS
deleted file mode 100644
index 17ea464..0000000
--- a/bluetooth/audio/aidl/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
deleted file mode 100644
index 17ea464..0000000
--- a/bluetooth/audio/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index f626db8..96cd9ef 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -508,6 +508,36 @@
   }
 }
 
+void BluetoothAudioSession::SetLatencyMode(LatencyMode latency_mode) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return;
+  }
+
+  auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+  }
+}
+
+void BluetoothAudioSession::SetCodecType(CodecType codec_type) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return;
+  }
+
+  auto hal_retval = stack_iface_->setCodecType(codec_type);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+  }
+}
+
 bool BluetoothAudioSession::IsAidlAvailable() {
   if (is_aidl_checked) return is_aidl_available;
   is_aidl_available =
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
index 73bc0f8..5adc0e2 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -20,6 +20,7 @@
 #include <aidl/android/hardware/audio/common/SourceMetadata.h>
 #include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
 #include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <aidl/android/hardware/bluetooth/audio/LatencyMode.h>
 #include <aidl/android/hardware/bluetooth/audio/SessionType.h>
 #include <fmq/AidlMessageQueue.h>
 #include <hardware/audio.h>
@@ -164,6 +165,8 @@
   bool GetPresentationPosition(PresentationPosition& presentation_position);
   void UpdateSourceMetadata(const struct source_metadata& source_metadata);
   void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
+  void SetLatencyMode(LatencyMode latency_mode);
+  void SetCodecType(CodecType codec_type);
 
   // The control function writes stream to FMQ
   size_t OutWritePcmData(const void* buffer, size_t bytes);
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 028c923..549d970 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -30,6 +30,7 @@
         ndk: {
             apex_available: [
                 "//apex_available:platform",
+                "com.android.bluetooth",
                 "com.android.media.swcodec",
                 "com.android.neuralnetworks",
             ],
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 842a75f..6fd4200 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -29,6 +29,13 @@
         cpp: {
             enabled: false,
         },
+        ndk: {
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.bluetooth",
+            ],
+            min_sdk_version: "29",
+        },
     },
     versions: ["1"],
 }
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index f751efc..b65b159 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -10,7 +10,7 @@
     <hal format="hidl" optional="false">
         <name>android.hardware.audio</name>
         <version>6.0</version>
-        <version>7.0</version>
+        <version>7.0-1</version>
         <interface>
             <name>IDevicesFactory</name>
             <instance>default</instance>
diff --git a/graphics/OWNERS b/graphics/OWNERS
new file mode 100644
index 0000000..75ceb23
--- /dev/null
+++ b/graphics/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 1075130
+
+# Graphics team
+adyabr@google.com
+alecmouri@google.com
+chrisforbes@google.com
+jreck@google.com
+lpy@google.com
+sumir@google.com
\ No newline at end of file
diff --git a/health/aidl/README.md b/health/aidl/README.md
index a64fe93..54d6758 100644
--- a/health/aidl/README.md
+++ b/health/aidl/README.md
@@ -60,7 +60,11 @@
 [android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
 Specifically:
 
-* You may ignore the `service` line. The name of the service does not matter.
+* For the `service` line, if the name of the service is **NOT**
+  `vendor.charger`, and there are actions
+  in the rc file triggered by `on property:init.svc.<name>=running` where
+  `<name>` is the name of your charger service, then you need a custom health
+  AIDL service.
 * If your service belongs to additional classes beside `charger`, you need a
   custom health AIDL service.
 * Modify the `seclabel` line. Replace `charger` with `charger_vendor`.
@@ -232,13 +236,19 @@
 It is recommended that you move the existing `service` entry with
 `class charger` to the `init.rc` file in your custom health service.
 
+If there are existing actions in the rc file triggered by
+`on property:init.svc.<name>=running`, where `<name>` is the name of your
+existing charger service (usually `vendor.charger`), then the name of the
+service must be kept as-is. If you modify the name of the service, the actions
+are not triggered properly.
+
 Modify the entry to invoke the health service binary with `--charger` argument.
 See
 [android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
 for an example:
 
 ```text
-service vendor.charger-tuna /vendor/bin/hw/android.hardware.health-service-tuna --charger
+service vendor.charger /vendor/bin/hw/android.hardware.health-service-tuna --charger
     class charger
     seclabel u:r:charger_vendor:s0
     # ...
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index 4258890..e052024 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -5,7 +5,7 @@
     capabilities WAKE_ALARM BLOCK_SUSPEND
     file /dev/kmsg w
 
-service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
+service vendor.charger /vendor/bin/hw/android.hardware.health-service.example --charger
     class charger
     seclabel u:r:charger_vendor:s0
     user system
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index dad3b8d..e3b8191 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -15,6 +15,7 @@
     ],
     imports: [
         "android.hardware.keymaster",
+        "android.hardware.security.keymint",
     ],
     stability: "vintf",
     backend: {
@@ -25,6 +26,7 @@
             vndk: {
                 enabled: true,
             },
+            apps_enabled: false,
         },
     },
     versions: [
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
index cd8d56b..9b96ea8 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
@@ -39,4 +39,5 @@
   int dataChunkSize;
   boolean isDirectAccess;
   @utf8InCpp String[] supportedDocTypes;
+  boolean isRemoteKeyProvisioningSupported = false;
 }
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
index c912c52..31ca8b1 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -38,6 +38,7 @@
   android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
   android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
   android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
+  android.hardware.security.keymint.IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
   const int STATUS_OK = 0;
   const int STATUS_FAILED = 1;
   const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
index 9a0fa9e..5377349 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -41,4 +41,5 @@
   byte[] addEntryValue(in byte[] content);
   @SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
   void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+  void setRemotelyProvisionedAttestationKey(in byte[] attestationKeyBlob, in byte[] attestationCertificate);
 }
diff --git a/identity/aidl/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
index d67739d..acd13b6 100644
--- a/identity/aidl/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
@@ -51,4 +51,19 @@
      *
      */
     @utf8InCpp String[] supportedDocTypes;
+
+    /**
+     * isRemoteKeyProvisioningSupported indicates whether or not the underlying implementation
+     * supports a remotely provisioned key for attestation or not. If this field is false, then
+     * the implementation only uses a factory-installed, fixed attestation key. If this field is
+     * true, then an IRemotelyProvisionedComponent is associated with the IIdentityCredentialStore,
+     * and a remotely provisioned key blob may be provided for credential key attestation.
+     *
+     * Note that remote provisioning is not required, even when it is supported. Implementations
+     * MUST use a factory-installed attestation key as a fallback for when there are no
+     * remotely provisioned keys available. This behavior mirrors keystore key attestation.
+     *
+     * This field was added in API version 4.
+     */
+    boolean isRemoteKeyProvisioningSupported = false;
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 84d6ed0..82b0a83 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -438,8 +438,9 @@
      * If the method is called on an instance obtained via IPresentationSession.getCredential(),
      * STATUS_FAILED must be returned.
      *
-     * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
-     *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+     * @param challenge a challenge set by the issuer to ensure freshness. Implementations must
+     *   support challenges that are at least 32 bytes. Fails with STATUS_INVALID_DATA if bigger
+     *   than 32 bytes.
      * @return a COSE_Sign1 signature described above.
      */
     byte[] deleteCredentialWithChallenge(in byte[] challenge);
@@ -463,8 +464,9 @@
      * If the method is called on an instance obtained via IPresentationSession.getCredential(),
      * STATUS_FAILED must be returned.
      *
-     * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
-     *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+     * @param challenge a challenge set by the issuer to ensure freshness. Implementations must
+     *   support challenges that are at least 32 bytes. Fails with STATUS_INVALID_DATA if bigger
+     *   than 32 bytes.
      * @return a COSE_Sign1 signature described above.
      */
     byte[] proveOwnership(in byte[] challenge);
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 86be7f5..d3e4da0 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -21,6 +21,7 @@
 import android.hardware.identity.IIdentityCredential;
 import android.hardware.identity.IPresentationSession;
 import android.hardware.identity.IWritableIdentityCredential;
+import android.hardware.security.keymint.IRemotelyProvisionedComponent;
 
 /**
  * IIdentityCredentialStore provides an interface to a secure store for user identity documents.
@@ -215,16 +216,16 @@
      * @return an IWritableIdentityCredential interface that provides operations to
      *     provision a credential.
      */
-    IWritableIdentityCredential createCredential(in @utf8InCpp String docType,
-                                                 in boolean testCredential);
+    IWritableIdentityCredential createCredential(
+            in @utf8InCpp String docType, in boolean testCredential);
 
     /**
      * getCredential retrieves an IIdentityCredential interface which allows use of a stored
      * Credential.
      *
-     * The cipher suite used to communicate with the remote verifier must also be specified. Currently
-     * only a single cipher-suite is supported. Support for other cipher suites may be added in a
-     * future version of this HAL.
+     * The cipher suite used to communicate with the remote verifier must also be specified.
+     * Currently only a single cipher-suite is supported. Support for other cipher suites may be
+     * added in a future version of this HAL.
      *
      * This method fails with STATUS_INVALID_DATA if the passed in credentialData cannot be
      * decoded or decrypted.
@@ -263,4 +264,23 @@
      * @return an IPresentationSession interface.
      */
     IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
+
+    /**
+     * Fetch the IRemotelyProvisionedComponent that is used to generate attestation keys for
+     * remote provisionining. Keys generated by this component are to be certified by a remote
+     * provisionined authority, then used to attest to credential keys via
+     * IWritableIdentityCredential.setRemotelyProvisionedAttestationKey.
+     *
+     * Support for this method is indicated by HardwareInformation. If the
+     * |isRemoteKeyProvisioningSupported| field is false, this method will fail with
+     * EX_UNSUPPORTED_OPERATION.
+     *
+     * This method was added in API version 4.
+     *
+     * @see
+     *         android.hardware.identity.IWritableIdentityCredential#setRemotelyProvisionedAttestationKey
+     *
+     * @return an IRemotelyProvisionedComponent that is used to generate attestation keys.
+     */
+    IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
 }
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 22bcf61..1c80cbb 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -127,11 +127,13 @@
      *     https://developer.android.com/training/articles/security-key-attestation#certificate_schema_attestationid
      *
      * @param attestationChallenge a challenge set by the issuer to ensure freshness. If
-     *    this is empty, the call fails with STATUS_INVALID_DATA.
+     *    this is empty, the call fails with STATUS_INVALID_DATA. Implementations must
+     *    support challenges of at least 32 bytes.
      *
      * @return the X.509 certificate chain for the credentialKey
      */
-    Certificate[] getAttestationCertificate(in byte[] attestationApplicationId, in byte[] attestationChallenge);
+    Certificate[] getAttestationCertificate(
+            in byte[] attestationApplicationId, in byte[] attestationChallenge);
 
     /**
      * Start the personalization process.
@@ -183,11 +185,11 @@
      *     in the secure environment. If this requirement is not met the call fails with
      *     STATUS_INVALID_DATA.
      *
-     * @return a structure with the passed-in data and MAC created with storageKey for authenticating
-     *     the data at a later point in time.
+     * @return a structure with the passed-in data and MAC created with storageKey for
+     *     authenticating the data at a later point in time.
      */
     SecureAccessControlProfile addAccessControlProfile(in int id, in Certificate readerCertificate,
-        in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
+            in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
 
     /**
      * Begins the process of adding an entry to the credential.  All access control profiles must be
@@ -209,7 +211,7 @@
      *     is not met this method fails with STATUS_INVALID_DATA.
      */
     void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace,
-        in @utf8InCpp String name, in int entrySize);
+            in @utf8InCpp String name, in int entrySize);
 
     /**
      * Continues the process of adding an entry, providing a value or part of a value.
@@ -221,8 +223,8 @@
      * chunk sizes must equal the value of the beginAddEntry() entrySize argument. If this
      * requirement is not met the call fails with STATUS_INVALID_DATA.
      *
-     * @param content is the entry value, encoded as CBOR. In the case the content exceeds gcmChunkSize,
-     *     this may be partial content up to gcmChunkSize bytes long.
+     * @param content is the entry value, encoded as CBOR. In the case the content exceeds
+     *     gcmChunkSize, this may be partial content up to gcmChunkSize bytes long.
      *
      * @return the encrypted and MACed content.  For directly-available credentials the contents are
      *     implementation-defined. For other credentials, the result contains
@@ -321,8 +323,7 @@
      *          }
      */
     @SuppressWarnings(value={"out-array"})
-    void finishAddingEntries(out byte[] credentialData,
-        out byte[] proofOfProvisioningSignature);
+    void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
 
     /**
      * Sets the expected size of the ProofOfProvisioning returned by finishAddingEntries(). This
@@ -336,4 +337,35 @@
      */
     void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
 
+    /**
+     * Sets the attestation key used to sign the credentialKey certificate. This method is used to
+     * support remotely provisioned attestation keys, removing the credential's dependency on any
+     * factory-provisioned attestation key.
+     *
+     * This method must be called before getAttestationCertificate. After this method is called,
+     * the certificate chain returned by getAttestationCertificate will contain a leaf certificate
+     * signed by attestationKeyBlob and the chain in attestationCertificate will make up the rest
+     * of the returned chain.
+     *
+     * Returns EX_UNSUPPORTED_FUNCTION if remote provisioning is not supported
+     * (see IIdentityCredentialStore.getHardwareInformation()).
+     *
+     * This method was added in API version 4.
+     *
+     * @param attestationKeyBlob is a key blob generated by the IRemotelyProvisionedComponent that
+     *     is returned by ICredentialStore.getRemotelyProvisionedComponent. The format is vendor-
+     *     specified, and matches the key blob returned by IKeyMintDevice.generateKey.
+     *
+     * @param attestationCertificate contains the X.509 certificate chain that certifies the
+     *     attestationKeyBlob. This certificate is expected to have been remotely provisioned
+     *     by a trusted authority. This parameter must contain a concatenated chain of DER-encoded
+     *     X.509 certificates. The certificates must be ordered such that the attestation key
+     *     certificate is first (starting at byte 0). The issuer certificate for the attestation
+     *     certificate immediately follows, continuing this chain to the final, root certificate.
+     *
+     * @see getAttestationCertificate
+     * @see android.hardware.identity.ICredentialStore#getRemotelyProvisionedComponent
+     */
+    void setRemotelyProvisionedAttestationKey(
+            in byte[] attestationKeyBlob, in byte[] attestationCertificate);
 }
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index ca24afa..32b3543 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -42,6 +42,7 @@
         "android.hardware.identity-support-lib",
         "android.hardware.identity-V4-ndk",
         "android.hardware.keymaster-V4-ndk",
+        "android.hardware.security.keymint-V2-ndk",
     ],
 }
 
@@ -81,6 +82,9 @@
     init_rc: ["identity-default.rc"],
     vintf_fragments: ["identity-default.xml"],
     vendor: true,
+    defaults: [
+        "keymint_use_latest_hal_aidl_ndk_static",
+    ],
     cflags: [
         "-Wall",
         "-Wextra",
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index c98a91e..3fd9f1d 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -267,25 +267,42 @@
 
 bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
                                size_t challengeSize, const uint8_t* applicationId,
-                               size_t applicationIdSize, bool testCredential, uint8_t* cert,
-                               size_t* certSize) {
-    vector<uint8_t> challengeVec(challengeSize);
-    memcpy(challengeVec.data(), challenge, challengeSize);
-
-    vector<uint8_t> applicationIdVec(applicationIdSize);
-    memcpy(applicationIdVec.data(), applicationId, applicationIdSize);
-
-    optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
-            android::hardware::identity::support::createEcKeyPairAndAttestation(
-                    challengeVec, applicationIdVec, testCredential);
-    if (!ret) {
-        eicDebug("Error generating CredentialKey and attestation");
-        return false;
+                               size_t applicationIdSize, bool testCredential,
+                               const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
+                               const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
+                               uint8_t* cert, size_t* certSize) {
+    vector<uint8_t> flatChain;
+    vector<uint8_t> keyPair;
+    vector<uint8_t> challengeVec(challenge, challenge + challengeSize);
+    vector<uint8_t> applicationIdVec(applicationId, applicationId + applicationIdSize);
+    if (attestationKeyBlob && attestationKeyBlobSize > 0 && attestationKeyCert &&
+        attestationKeyCertSize > 0) {
+        vector<uint8_t> attestationKeyBlobVec(attestationKeyBlob,
+                                              attestationKeyBlob + attestationKeyBlobSize);
+        vector<uint8_t> attestationKeyCertVec(attestationKeyCert,
+                                              attestationKeyCert + attestationKeyCertSize);
+        optional<std::pair<vector<uint8_t>, vector<uint8_t>>> keyAndCert =
+                android::hardware::identity::support::createEcKeyPairWithAttestationKey(
+                        challengeVec, applicationIdVec, attestationKeyBlobVec,
+                        attestationKeyCertVec, testCredential);
+        if (!keyAndCert) {
+            eicDebug("Error generating CredentialKey and attestation");
+            return false;
+        }
+        keyPair = std::move(keyAndCert->first);
+        flatChain = std::move(keyAndCert->second);
+    } else {
+        optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
+                android::hardware::identity::support::createEcKeyPairAndAttestation(
+                        challengeVec, applicationIdVec, testCredential);
+        if (!ret) {
+            eicDebug("Error generating CredentialKey and attestation");
+            return false;
+        }
+        keyPair = std::move(ret->first);
+        flatChain = android::hardware::identity::support::certificateChainJoin(ret->second);
     }
 
-    // Extract certificate chain.
-    vector<uint8_t> flatChain =
-            android::hardware::identity::support::certificateChainJoin(ret.value().second);
     if (*certSize < flatChain.size()) {
         eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
                  flatChain.size());
@@ -296,7 +313,7 @@
 
     // Extract private key.
     optional<vector<uint8_t>> privKey =
-            android::hardware::identity::support::ecKeyPairGetPrivateKey(ret.value().first);
+            android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
     if (!privKey) {
         eicDebug("Error extracting private key");
         return false;
@@ -520,10 +537,12 @@
 #ifdef EIC_DEBUG
 
 void eicPrint(const char* format, ...) {
+    char buf[1024];
     va_list args;
     va_start(args, format);
-    vfprintf(stderr, format, args);
+    vsnprintf(buf, sizeof(buf), format, args);
     va_end(args);
+    LOG(INFO) << buf;
 }
 
 void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index 91e634c..9b9a749 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -155,7 +155,11 @@
     size_t publicKeyCertSize = sizeof publicKeyCert;
     if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
                                             applicationId.data(), applicationId.size(),
-                                            publicKeyCert, &publicKeyCertSize)) {
+                                            /*attestationKeyBlob=*/nullptr,
+                                            /*attestationKeyBlobSize=*/0,
+                                            /*attestationKeyCert=*/nullptr,
+                                            /*attestationKeyCertSize=*/0, publicKeyCert,
+                                            &publicKeyCertSize)) {
         return std::nullopt;
     }
     vector<uint8_t> pubKeyCert(publicKeyCertSize);
@@ -163,6 +167,23 @@
     return pubKeyCert;
 }
 
+optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKeyUsingRkp(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+        const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attstationKeyCert) {
+    size_t publicKeyCertSize = 4096;
+    vector<uint8_t> publicKeyCert(publicKeyCertSize);
+    if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
+                                            applicationId.data(), applicationId.size(),
+                                            attestationKeyBlob.data(), attestationKeyBlob.size(),
+                                            attstationKeyCert.data(), attstationKeyCert.size(),
+                                            publicKeyCert.data(), &publicKeyCertSize)) {
+        LOG(ERROR) << "error creating credential key";
+        return std::nullopt;
+    }
+    publicKeyCert.resize(publicKeyCertSize);
+    return publicKeyCert;
+}
+
 bool FakeSecureHardwareProvisioningProxy::startPersonalization(
         int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
         size_t expectedProofOfProvisioningSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index df98c7a..2512074 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -43,6 +43,11 @@
     optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
                                                   const vector<uint8_t>& applicationId) override;
 
+    optional<vector<uint8_t>> createCredentialKeyUsingRkp(
+            const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+            const vector<uint8_t>& attestationKeyBlob,
+            const vector<uint8_t>& attestationKeyCert) override;
+
     bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
                               const string& docType,
                               size_t expectedProofOfProvisioningSize) override;
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 7678ecb..ff80752 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -1012,8 +1012,8 @@
                 IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
     }
     shared_ptr<WritableIdentityCredential> wc =
-            ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_,
-                                                                 testCredential_);
+            ndk::SharedRefBase::make<WritableIdentityCredential>(
+                    provisioningHwProxy, docType_, testCredential_, hardwareInformation_);
     if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 2935fb8..5929829 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -48,11 +48,13 @@
   public:
     IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
                        const vector<uint8_t>& credentialData,
-                       std::shared_ptr<PresentationSession> session)
+                       std::shared_ptr<PresentationSession> session,
+                       HardwareInformation hardwareInformation)
         : hwProxyFactory_(hwProxyFactory),
           credentialData_(credentialData),
           session_(std::move(session)),
           numStartRetrievalCalls_(0),
+          hardwareInformation_(std::move(hardwareInformation)),
           expectedDeviceNameSpacesSize_(0) {}
 
     // Parses and decrypts credentialData_, return a status code from
@@ -103,6 +105,7 @@
     vector<uint8_t> credentialData_;
     shared_ptr<PresentationSession> session_;
     int numStartRetrievalCalls_;
+    HardwareInformation hardwareInformation_;
 
     // Set by initialize()
     string docType_;
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
index 4703ffe..bbc2cef 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.cpp
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "IdentityCredentialStore"
 
 #include <android-base/logging.h>
+#include <android/binder_manager.h>
 
 #include "IdentityCredential.h"
 #include "IdentityCredentialStore.h"
@@ -25,15 +26,24 @@
 
 namespace aidl::android::hardware::identity {
 
+using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+
+IdentityCredentialStore::IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
+                                                 optional<string> remotelyProvisionedComponent)
+    : hwProxyFactory_(hwProxyFactory),
+      remotelyProvisionedComponentName_(remotelyProvisionedComponent) {
+    hardwareInformation_.credentialStoreName = "Identity Credential Reference Implementation";
+    hardwareInformation_.credentialStoreAuthorName = "Google";
+    hardwareInformation_.dataChunkSize = kGcmChunkSize;
+    hardwareInformation_.isDirectAccess = false;
+    hardwareInformation_.supportedDocTypes = {};
+    hardwareInformation_.isRemoteKeyProvisioningSupported =
+            remotelyProvisionedComponentName_.has_value();
+}
+
 ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
         HardwareInformation* hardwareInformation) {
-    HardwareInformation hw;
-    hw.credentialStoreName = "Identity Credential Reference Implementation";
-    hw.credentialStoreAuthorName = "Google";
-    hw.dataChunkSize = kGcmChunkSize;
-    hw.isDirectAccess = false;
-    hw.supportedDocTypes = {};
-    *hardwareInformation = hw;
+    *hardwareInformation = hardwareInformation_;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -42,7 +52,8 @@
         shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
     sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
     shared_ptr<WritableIdentityCredential> wc =
-            ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential);
+            ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential,
+                                                                 hardwareInformation_);
     if (!wc->initialize()) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
@@ -63,7 +74,7 @@
     }
 
     shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
-            hwProxyFactory_, credentialData, nullptr /* session */);
+            hwProxyFactory_, credentialData, nullptr /* session */, hardwareInformation_);
     auto ret = credential->initialize();
     if (ret != IIdentityCredentialStore::STATUS_OK) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -83,8 +94,8 @@
     }
 
     sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
-    shared_ptr<PresentationSession> session =
-            ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy);
+    shared_ptr<PresentationSession> session = ndk::SharedRefBase::make<PresentationSession>(
+            hwProxyFactory_, hwProxy, hardwareInformation_);
     auto ret = session->initialize();
     if (ret != IIdentityCredentialStore::STATUS_OK) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -94,4 +105,23 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredentialStore::getRemotelyProvisionedComponent(
+        shared_ptr<IRemotelyProvisionedComponent>* outRemotelyProvisionedComponent) {
+    if (!remotelyProvisionedComponentName_) {
+        return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
+                EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
+    }
+
+    ndk::SpAIBinder binder(
+            AServiceManager_waitForService(remotelyProvisionedComponentName_->c_str()));
+    if (binder.get() == nullptr) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Unable to get remotely provisioned component"));
+    }
+
+    *outRemotelyProvisionedComponent = IRemotelyProvisionedComponent::fromBinder(binder);
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h
index 77b894d..dd1261b 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.h
+++ b/identity/aidl/default/common/IdentityCredentialStore.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
 
 #include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 
 #include "SecureHardwareProxy.h"
 
@@ -25,14 +26,18 @@
 
 using ::android::sp;
 using ::android::hardware::identity::SecureHardwareProxyFactory;
+using ::std::optional;
 using ::std::shared_ptr;
 using ::std::string;
 using ::std::vector;
 
 class IdentityCredentialStore : public BnIdentityCredentialStore {
   public:
-    IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory)
-        : hwProxyFactory_(hwProxyFactory) {}
+    // If remote key provisioning is supported, pass the service name for the correct
+    // IRemotelyProvisionedComponent to the remotelyProvisionedComponent parameter. Else
+    // pass std::nullopt to indicate remote key provisioning is not supported.
+    IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
+                            optional<string> remotelyProvisionedComponent);
 
     // The GCM chunk size used by this implementation is 64 KiB.
     static constexpr size_t kGcmChunkSize = 64 * 1024;
@@ -50,8 +55,14 @@
     ndk::ScopedAStatus createPresentationSession(
             CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
 
+    ndk::ScopedAStatus getRemotelyProvisionedComponent(
+            shared_ptr<::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent>*
+                    outRemotelyProvisionedComponent) override;
+
   private:
     sp<SecureHardwareProxyFactory> hwProxyFactory_;
+    optional<string> remotelyProvisionedComponentName_;
+    HardwareInformation hardwareInformation_;
 };
 
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
index fbd8972..2eb7f2e 100644
--- a/identity/aidl/default/common/PresentationSession.cpp
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -122,8 +122,8 @@
 ndk::ScopedAStatus PresentationSession::getCredential(
         const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
     shared_ptr<PresentationSession> p = ref<PresentationSession>();
-    shared_ptr<IdentityCredential> credential =
-            ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p);
+    shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
+            hwProxyFactory_, credentialData, p, hardwareInformation_);
     int ret = credential->initialize();
     if (ret != IIdentityCredentialStore::STATUS_OK) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
index 76ca67b..4cb174a 100644
--- a/identity/aidl/default/common/PresentationSession.h
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -38,8 +38,11 @@
 class PresentationSession : public BnPresentationSession {
   public:
     PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
-                        sp<SecureHardwareSessionProxy> hwProxy)
-        : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {}
+                        sp<SecureHardwareSessionProxy> hwProxy,
+                        HardwareInformation hardwareInformation)
+        : hwProxyFactory_(std::move(hwProxyFactory)),
+          hwProxy_(std::move(hwProxy)),
+          hardwareInformation_(std::move(hardwareInformation)) {}
 
     virtual ~PresentationSession();
 
@@ -65,6 +68,7 @@
     // Set by constructor
     sp<SecureHardwareProxyFactory> hwProxyFactory_;
     sp<SecureHardwareSessionProxy> hwProxy_;
+    HardwareInformation hardwareInformation_;
 
     // Set by initialize()
     uint64_t id_;
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index a580444..9f63ad8 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -82,6 +82,18 @@
     virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
                                                           const vector<uint8_t>& applicationId) = 0;
 
+    // Returns public key certificate with a remotely provisioned attestation key.
+    //
+    // This returns a single certificate that is signed by the given |attestationKeyBlob|.
+    // The implementation of eicOpsCreateCredentialKey() on the TA side must coordinate
+    // with its corresponding keymint implementation to sign using the attestation key. The
+    // |attestationKeyCert| parameter is the certificates for |attestationKeyBlob|,
+    // formatted as concatenated, DER-encoded, X.509 certificates.
+    virtual optional<vector<uint8_t>> createCredentialKeyUsingRkp(
+            const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+            const vector<uint8_t>& attestationKeyBlob,
+            const vector<uint8_t>& attestationKeyCert) = 0;
+
     virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
                                       const string& docType,
                                       size_t expectedProofOfProvisioningSize) = 0;
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index 200ee61..e420a7b 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -79,8 +79,15 @@
                 IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
     }
 
-    optional<vector<uint8_t>> certChain =
-            hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
+    optional<vector<uint8_t>> certChain;
+    if (attestationKeyBlob_ && attestationCertificateChain_) {
+        certChain = hwProxy_->createCredentialKeyUsingRkp(
+                attestationChallenge, attestationApplicationId, *attestationKeyBlob_,
+                attestationCertificateChain_->at(0));
+    } else {
+        certChain = hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
+    }
+
     if (!certChain) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
@@ -95,8 +102,14 @@
     }
 
     *outCertificateChain = vector<Certificate>();
-    for (const vector<uint8_t>& cert : certs.value()) {
-        Certificate c = Certificate();
+    for (vector<uint8_t>& cert : certs.value()) {
+        Certificate c;
+        c.encodedCertificate = std::move(cert);
+        outCertificateChain->push_back(std::move(c));
+    }
+
+    for (const vector<uint8_t>& cert : *attestationCertificateChain_) {
+        Certificate c;
         c.encodedCertificate = cert;
         outCertificateChain->push_back(std::move(c));
     }
@@ -402,4 +415,36 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus WritableIdentityCredential::setRemotelyProvisionedAttestationKey(
+        const vector<uint8_t>& attestationKeyBlob,
+        const vector<uint8_t>& attestationCertificateChain) {
+    if (!hardwareInformation_.isRemoteKeyProvisioningSupported) {
+        return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
+                EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
+    }
+
+    if (attestationKeyBlob.empty() || attestationCertificateChain.empty()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Empty data passed to setRemotlyProvisionedAttestationKey"));
+    }
+
+    if (attestationKeyBlob_.has_value()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Attestation key already set"));
+    }
+
+    optional<vector<vector<uint8_t>>> certs =
+            support::certificateChainSplit(attestationCertificateChain);
+    if (!certs) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error splitting chain into separate certificates"));
+    }
+
+    attestationKeyBlob_ = attestationKeyBlob;
+    attestationCertificateChain_ = *certs;
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h
index 36ad430..39d32c9 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.h
+++ b/identity/aidl/default/common/WritableIdentityCredential.h
@@ -30,6 +30,7 @@
 
 using ::android::sp;
 using ::android::hardware::identity::SecureHardwareProvisioningProxy;
+using ::std::optional;
 using ::std::set;
 using ::std::string;
 using ::std::vector;
@@ -41,8 +42,11 @@
     // For an updated credential, call initializeForUpdate() right after construction.
     //
     WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
-                               bool testCredential)
-        : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
+                               bool testCredential, HardwareInformation hardwareInformation)
+        : hwProxy_(hwProxy),
+          docType_(docType),
+          testCredential_(testCredential),
+          hardwareInformation_(std::move(hardwareInformation)) {}
 
     ~WritableIdentityCredential();
 
@@ -78,11 +82,16 @@
             vector<uint8_t>* outCredentialData,
             vector<uint8_t>* outProofOfProvisioningSignature) override;
 
+    ndk::ScopedAStatus setRemotelyProvisionedAttestationKey(
+            const vector<uint8_t>& attestationKeyBlob,
+            const vector<uint8_t>& attestationCertificateChain) override;
+
   private:
     // Set by constructor.
     sp<SecureHardwareProvisioningProxy> hwProxy_;
     string docType_;
     bool testCredential_;
+    HardwareInformation hardwareInformation_;
 
     // This is set in initialize().
     bool startPersonalizationCalled_;
@@ -109,6 +118,10 @@
     vector<int32_t> entryAccessControlProfileIds_;
     vector<uint8_t> entryBytes_;
     set<string> allNameSpaces_;
+
+    // Remotely provisioned attestation data, set via setRemotelyProvisionedAttestationKey
+    optional<vector<uint8_t>> attestationKeyBlob_;
+    optional<vector<vector<uint8_t>>> attestationCertificateChain_;
 };
 
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h
index aa26e62..df96c7d 100644
--- a/identity/aidl/default/libeic/EicOps.h
+++ b/identity/aidl/default/libeic/EicOps.h
@@ -196,13 +196,19 @@
 
 // Generates CredentialKey plus an attestation certificate.
 //
-// The attestation certificate will be signed by the attestation keys the secure
-// area has been provisioned with. The given |challenge| and |applicationId|
-// will be used as will |testCredential|.
+// If |attestationKeyBlob| is non-NULL, the certificate must be signed by the
+// the provided attestation key. Else, the certificate must be signed by the
+// attestation key that the secure area has been factory provisioned with. The
+// given |challenge|, |applicationId|, and |testCredential| must be signed
+// into the attestation.
 //
-// The generated certificate will be in X.509 format and returned in |cert|
-// and |certSize| must be set to the size of this array and this function will
-// set it to the size of the certification chain on successfully return.
+// When |attestationKeyBlob| is non-NULL, then |attestationKeyCert| must
+// also be passed so that the underlying implementation can properly chain up
+// the newly-generated certificate to the existing chain.
+//
+// The generated certificate must be in X.509 format and returned in |cert|
+// and |certSize| must be set to the size of this array. This function must
+// set |certSize| to the size of the certification chain on successfully return.
 //
 // This may return either a single certificate or an entire certificate
 // chain. If it returns only a single certificate, the implementation of
@@ -211,8 +217,10 @@
 //
 bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
                                size_t challengeSize, const uint8_t* applicationId,
-                               size_t applicationIdSize, bool testCredential, uint8_t* cert,
-                               size_t* certSize);  // inout
+                               size_t applicationIdSize, bool testCredential,
+                               const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
+                               const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
+                               uint8_t* /*out*/ cert, size_t* /*inout*/ certSize);
 
 // Generate an X.509 certificate for the key identified by |publicKey| which
 // must be of the form returned by eicOpsCreateEcKey().
diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c
index a241b71..ff009dd 100644
--- a/identity/aidl/default/libeic/EicProvisioning.c
+++ b/identity/aidl/default/libeic/EicProvisioning.c
@@ -133,7 +133,10 @@
 
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
-                                        size_t applicationIdSize, uint8_t* publicKeyCert,
+                                        size_t applicationIdSize, const uint8_t* attestationKeyBlob,
+                                        size_t attestationKeyBlobSize,
+                                        const uint8_t* attestationKeyCert,
+                                        size_t attestationKeyCertSize, uint8_t* publicKeyCert,
                                         size_t* publicKeyCertSize) {
     if (ctx->isUpdate) {
         eicDebug("Cannot create CredentialKey on update");
@@ -142,7 +145,9 @@
 
     if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
                                    applicationId, applicationIdSize, ctx->testCredential,
-                                   publicKeyCert, publicKeyCertSize)) {
+                                   attestationKeyBlob, attestationKeyBlobSize, attestationKeyCert,
+                                   attestationKeyCertSize, publicKeyCert, publicKeyCertSize)) {
+        eicDebug("Error creating credential key");
         return false;
     }
     return true;
diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h
index d94f8f1..2619bfc 100644
--- a/identity/aidl/default/libeic/EicProvisioning.h
+++ b/identity/aidl/default/libeic/EicProvisioning.h
@@ -77,7 +77,10 @@
 
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
-                                        size_t applicationIdSize, uint8_t* publicKeyCert,
+                                        size_t applicationIdSize, const uint8_t* attestationKeyBlob,
+                                        size_t attestationKeyBlobSize,
+                                        const uint8_t* attestationKeyCert,
+                                        size_t attestationKeyCertSize, uint8_t* publicKeyCert,
                                         size_t* publicKeyCertSize);
 
 bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
diff --git a/identity/aidl/default/service.cpp b/identity/aidl/default/service.cpp
index 78f4fbc..ed3c4cb 100644
--- a/identity/aidl/default/service.cpp
+++ b/identity/aidl/default/service.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "android.hardware.identity-service"
 
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -26,20 +27,35 @@
 
 using ::android::sp;
 using ::android::base::InitLogging;
+using ::android::base::LogdLogger;
+using ::android::base::LogId;
+using ::android::base::LogSeverity;
 using ::android::base::StderrLogger;
 
 using ::aidl::android::hardware::identity::IdentityCredentialStore;
+using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
 using ::android::hardware::identity::FakeSecureHardwareProxyFactory;
 using ::android::hardware::identity::SecureHardwareProxyFactory;
 
+void ComboLogger(LogId id, LogSeverity severity, const char* tag, const char* file,
+                 unsigned int line, const char* message) {
+    StderrLogger(id, severity, tag, file, line, message);
+
+    static LogdLogger logdLogger;
+    logdLogger(id, severity, tag, file, line, message);
+}
+
 int main(int /*argc*/, char* argv[]) {
-    InitLogging(argv, StderrLogger);
+    InitLogging(argv, ComboLogger);
 
     sp<SecureHardwareProxyFactory> hwProxyFactory = new FakeSecureHardwareProxyFactory();
+    const std::string remotelyProvisionedComponentName =
+            std::string(IRemotelyProvisionedComponent::descriptor) + "/default";
 
     ABinderProcess_setThreadPoolMaxThreadCount(0);
     std::shared_ptr<IdentityCredentialStore> store =
-            ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory);
+            ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory,
+                                                              remotelyProvisionedComponentName);
 
     const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 7b6f2c8..20faeee 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -11,6 +11,8 @@
     name: "VtsHalIdentityTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "keymint_use_latest_hal_aidl_cpp_static",
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     cflags: [
@@ -32,12 +34,15 @@
     ],
     shared_libs: [
         "libbinder",
+        "libbinder_ndk",
         "libcrypto",
     ],
     static_libs: [
+        "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libcppcose_rkp",
         "libkeymaster_portable",
+        "libkeymint_vts_test_utils",
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
         "android.hardware.identity-support-lib",
@@ -46,9 +51,23 @@
         "android.hardware.keymaster-V4-ndk",
         "libkeymaster4support",
         "libkeymaster4_1support",
+        "libkeymint_remote_prov_support",
     ],
     test_suites: [
         "general-tests",
         "vts",
     ],
 }
+
+java_test_host {
+    name: "IdentityCredentialImplementedTest",
+    libs: [
+        "tradefed",
+        "vts-core-tradefed-harness",
+    ],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "vts",
+    ],
+    test_config: "IdentityCredentialImplementedTest.xml",
+}
diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp
index 7627c9c..a126463 100644
--- a/identity/aidl/vts/DeleteCredentialTests.cpp
+++ b/identity/aidl/vts/DeleteCredentialTests.cpp
@@ -146,7 +146,9 @@
                                 credentialData_, &credential)
                         .isOk());
 
-    vector<uint8_t> challenge = {65, 66, 67};
+    // Implementations must support at least 32 bytes.
+    string challengeString = "0123456789abcdef0123456789abcdef";
+    vector<uint8_t> challenge(challengeString.begin(), challengeString.end());
     vector<uint8_t> proofOfDeletionSignature;
     ASSERT_TRUE(
             credential->deleteCredentialWithChallenge(challenge, &proofOfDeletionSignature).isOk());
@@ -154,8 +156,13 @@
             support::coseSignGetPayload(proofOfDeletionSignature);
     ASSERT_TRUE(proofOfDeletion);
     string cborPretty = cppbor::prettyPrint(proofOfDeletion.value(), 32, {});
-    EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {0x41, 0x42, 0x43}, true, ]",
-              cborPretty);
+    EXPECT_EQ(
+            "['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {"
+            "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+            "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, "
+            "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+            "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, true, ]",
+            cborPretty);
     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {},  // Additional data
                                                  credentialPubKey_));
 }
diff --git a/identity/aidl/vts/IdentityCredentialImplementedTest.xml b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
new file mode 100644
index 0000000..1d76a74
--- /dev/null
+++ b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<configuration description="Runs IdentityCredentialImplementedTest">
+  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+  <test class="com.android.tradefed.testtype.HostTest" >
+    <option name="jar" value="IdentityCredentialImplementedTest.jar" />
+  </test>
+</configuration>
diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp
index c622193..f8ec670 100644
--- a/identity/aidl/vts/ProveOwnershipTests.cpp
+++ b/identity/aidl/vts/ProveOwnershipTests.cpp
@@ -125,14 +125,22 @@
                                 credentialData_, &credential)
                         .isOk());
 
-    vector<uint8_t> challenge = {17, 18};
+    // Implementations must support at least 32 bytes.
+    string challengeString = "0123456789abcdef0123456789abcdef";
+    vector<uint8_t> challenge(challengeString.begin(), challengeString.end());
     vector<uint8_t> proofOfOwnershipSignature;
     ASSERT_TRUE(credential->proveOwnership(challenge, &proofOfOwnershipSignature).isOk());
     optional<vector<uint8_t>> proofOfOwnership =
             support::coseSignGetPayload(proofOfOwnershipSignature);
     ASSERT_TRUE(proofOfOwnership);
     string cborPretty = cppbor::prettyPrint(proofOfOwnership.value(), 32, {});
-    EXPECT_EQ("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {0x11, 0x12}, true, ]", cborPretty);
+    EXPECT_EQ(
+            "['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {"
+            "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+            "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, "
+            "0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, "
+            "0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, true, ]",
+            cborPretty);
     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfOwnershipSignature, {},  // Additional data
                                                  credentialPubKey_));
 }
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index 1148cb0..f3d7c30 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -20,12 +20,16 @@
 
 #include <android-base/logging.h>
 
+#include <KeyMintAidlTestBase.h>
 #include <aidl/Gtest.h>
+#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
 #include <android-base/stringprintf.h>
 #include <keymaster/km_openssl/openssl_utils.h>
 #include <keymasterV4_1/attestation_record.h>
-#include <charconv>
+#include <keymint_support/openssl_utils.h>
+#include <openssl/evp.h>
 
+#include <charconv>
 #include <map>
 
 namespace android::hardware::identity::test_utils {
@@ -36,10 +40,13 @@
 using std::string;
 using std::vector;
 
+using ::aidl::android::hardware::security::keymint::test::check_maced_pubkey;
+using ::aidl::android::hardware::security::keymint::test::p256_pub_key;
 using ::android::sp;
 using ::android::String16;
 using ::android::base::StringPrintf;
 using ::android::binder::Status;
+using ::android::hardware::security::keymint::MacedPublicKey;
 using ::keymaster::X509_Ptr;
 
 bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
@@ -58,6 +65,77 @@
     }
 }
 
+optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
+        const MacedPublicKey& macedPublicKey) {
+    // The helper library uses the NDK symbols, so play a little trickery here to convert
+    // the data into the proper type so we can reuse the helper function to get the pubkey.
+    ::aidl::android::hardware::security::keymint::MacedPublicKey ndkMacedPublicKey;
+    ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
+
+    vector<uint8_t> publicKeyBits;
+    check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/true, &publicKeyBits);
+
+    ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
+    p256_pub_key(publicKeyBits, &publicKey);
+
+    // Generate an arbitrary root key for our chain
+    bssl::UniquePtr<EC_KEY> ecRootKey(EC_KEY_new());
+    bssl::UniquePtr<EVP_PKEY> rootKey(EVP_PKEY_new());
+    if (ecRootKey.get() == nullptr || rootKey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+
+    bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    if (group.get() == nullptr) {
+        LOG(ERROR) << "Error creating EC group by curve name";
+        return {};
+    }
+
+    if (EC_KEY_set_group(ecRootKey.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ecRootKey.get()) != 1 || EC_KEY_check_key(ecRootKey.get()) < 0) {
+        LOG(ERROR) << "Error generating key";
+        return {};
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(rootKey.get(), ecRootKey.get()) != 1) {
+        LOG(ERROR) << "Error getting private key";
+        return {};
+    }
+
+    // The VTS test does not fully validate the chain, so we're ok without the proper CA extensions.
+    map<string, vector<uint8_t>> extensions;
+
+    // Now make a self-signed cert
+    optional<vector<uint8_t>> root = support::ecPublicKeyGenerateCertificate(
+            rootKey.get(), rootKey.get(),
+            /*serialDecimal=*/"31415",
+            /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+            /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+            /*validityNotBefore=*/time(nullptr),
+            /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
+    if (!root) {
+        LOG(ERROR) << "Error generating root cert";
+        return std::nullopt;
+    }
+
+    // Now sign a CA cert so that we have a chain that's good enough to satisfy
+    // the VTS tests.
+    optional<vector<uint8_t>> intermediate = support::ecPublicKeyGenerateCertificate(
+            publicKey.get(), rootKey.get(),
+            /*serialDecimal=*/"42",
+            /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
+            /*subject=*/"Android IdentityCredential VTS Test Attestation Certificate",
+            /*validityNotBefore=*/time(nullptr),
+            /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
+    if (!intermediate) {
+        LOG(ERROR) << "Error generating intermediate cert";
+        return std::nullopt;
+    }
+
+    return vector<vector<uint8_t>>{std::move(*intermediate), std::move(*root)};
+}
+
 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
     vector<uint8_t> privKey;
     return generateReaderCertificate(serialDecimal, &privKey);
diff --git a/identity/aidl/vts/Util.h b/identity/aidl/vts/Util.h
index 80e52a2..b120dc9 100644
--- a/identity/aidl/vts/Util.h
+++ b/identity/aidl/vts/Util.h
@@ -19,6 +19,7 @@
 
 #include <android/hardware/identity/IIdentityCredentialStore.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <android/hardware/security/keymint/MacedPublicKey.h>
 #include <cppbor.h>
 #include <cppbor_parse.h>
 #include <gtest/gtest.h>
@@ -97,6 +98,9 @@
 bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
                              sp<IIdentityCredentialStore>& credentialStore, bool testCredential);
 
+optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
+        const ::android::hardware::security::keymint::MacedPublicKey& macedPublicKey);
+
 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal);
 
 optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
diff --git a/identity/aidl/vts/VtsAttestationTests.cpp b/identity/aidl/vts/VtsAttestationTests.cpp
index e12fe05..7caa259 100644
--- a/identity/aidl/vts/VtsAttestationTests.cpp
+++ b/identity/aidl/vts/VtsAttestationTests.cpp
@@ -66,7 +66,8 @@
     ASSERT_TRUE(setupWritableCredential(writableCredential, credentialStore_,
                                         false /* testCredential */));
 
-    string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
+    // Must support at least 32 bytes.
+    string challenge = "0123456789abcdef0123456789abcdef";
     vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
     vector<Certificate> attestationCertificate;
     string applicationId = "Attestation Verification";
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index bc37020..94d4c88 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -18,6 +18,8 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
 #include <android-base/logging.h>
 #include <android/hardware/identity/IIdentityCredentialStore.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
@@ -42,6 +44,8 @@
 using ::android::sp;
 using ::android::String16;
 using ::android::binder::Status;
+using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+using ::android::hardware::security::keymint::MacedPublicKey;
 
 class IdentityCredentialTests : public testing::TestWithParam<string> {
   public:
@@ -101,6 +105,103 @@
                                                attestationApplicationId, false);
 }
 
+TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) {
+    HardwareInformation hwInfo;
+    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+    if (!hwInfo.isRemoteKeyProvisioningSupported) {
+        GTEST_SKIP() << "Remote provisioning is not supported";
+    }
+
+    Status result;
+
+    sp<IWritableIdentityCredential> writableCredential;
+    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+                                                    false /* testCredential */));
+
+    sp<IRemotelyProvisionedComponent> rpc;
+    result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    MacedPublicKey macedPublicKey;
+    std::vector<uint8_t> attestationKey;
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
+            test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
+    ASSERT_TRUE(remotelyProvisionedCertChain);
+
+    vector<uint8_t> concatenatedCerts;
+    for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
+        concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
+    }
+    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+                                                                      concatenatedCerts);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
+    vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
+    vector<Certificate> attestationCertificate;
+    vector<uint8_t> attestationApplicationId = {1};
+
+    result = writableCredential->getAttestationCertificate(
+            attestationApplicationId, attestationChallenge, &attestationCertificate);
+
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
+                                               attestationApplicationId, false);
+
+    ASSERT_EQ(remotelyProvisionedCertChain->size() + 1, attestationCertificate.size());
+    for (size_t i = 0; i < remotelyProvisionedCertChain->size(); ++i) {
+        ASSERT_EQ(remotelyProvisionedCertChain->at(i),
+                  attestationCertificate[i + 1].encodedCertificate)
+                << "Certificate mismatch (cert index " << i + 1 << " out of "
+                << attestationCertificate.size() << " total certs)";
+    }
+}
+
+TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) {
+    HardwareInformation hwInfo;
+    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+    if (!hwInfo.isRemoteKeyProvisioningSupported) {
+        GTEST_SKIP() << "Remote provisioning is not supported";
+    }
+
+    sp<IRemotelyProvisionedComponent> rpc;
+    Status result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    MacedPublicKey macedPublicKey;
+    std::vector<uint8_t> attestationKey;
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
+            test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
+    ASSERT_TRUE(remotelyProvisionedCertChain);
+
+    vector<uint8_t> concatenatedCerts;
+    for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
+        concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
+    }
+
+    sp<IWritableIdentityCredential> writableCredential;
+    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+                                                    /*testCredential=*/false));
+
+    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+                                                                      concatenatedCerts);
+    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
+
+    // Now try again, and verify that the implementation rejects it.
+    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
+                                                                      concatenatedCerts);
+    EXPECT_FALSE(result.isOk());
+}
+
 TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
     Status result;
 
diff --git a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
new file mode 100644
index 0000000..19568af
--- /dev/null
+++ b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.security.identity;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.RequiresDevice;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class IdentityCredentialImplementedTest extends BaseHostJUnit4Test {
+    // Returns the ro.vendor.api_level or 0 if not set.
+    //
+    // Throws NumberFormatException if ill-formatted.
+    //
+    // Throws DeviceNotAvailableException if device is not available.
+    //
+    private int getVendorApiLevel() throws NumberFormatException, DeviceNotAvailableException {
+        String vendorApiLevelString =
+                getDevice().executeShellCommand("getprop ro.vendor.api_level").trim();
+        if (vendorApiLevelString.isEmpty()) {
+            return 0;
+        }
+        return Integer.parseInt(vendorApiLevelString);
+    }
+
+    // As of Android 13 (API level 32), Identity Credential is required at feature version 202201
+    // or newer.
+    //
+    @RequiresDevice
+    @Test
+    public void testIdentityCredentialIsImplemented() throws Exception {
+        int vendorApiLevel = getVendorApiLevel();
+        assumeTrue(vendorApiLevel >= 32);
+
+        final String minimumFeatureVersionNeeded = "202201";
+
+        String result = getDevice().executeShellCommand(
+                "pm has-feature android.hardware.identity_credential "
+                + minimumFeatureVersionNeeded);
+        if (!result.trim().equals("true")) {
+            fail("Identity Credential feature version " + minimumFeatureVersionNeeded
+                    + " required but not found");
+        }
+    }
+}
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 3b91de6..82746d6 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -17,6 +17,8 @@
 #ifndef IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
 #define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
 
+#include <openssl/evp.h>
+
 #include <cstdint>
 #include <map>
 #include <optional>
@@ -128,6 +130,15 @@
         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
         bool isTestCredential);
 
+// Alternate version of createEcKeyPairAndAttestation that accepts an attestation key
+// blob to sign the generated key. Only a single certificate is returned, rather than
+// a full chain.
+//
+optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+        const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
+        bool isTestCredential);
+
 // (TODO: remove when no longer used by 3rd party.)
 optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
         const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
@@ -240,6 +251,13 @@
         time_t validityNotBefore, time_t validityNotAfter,
         const map<string, vector<uint8_t>>& extensions);
 
+// Identical behavior to the above version of ecPublicKeyGenerateCertificate, except this
+// overload takes OpenSSL key parameters instead of key bitstrings as inputs.
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
+        const string& issuer, const string& subject, time_t validityNotBefore,
+        time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions);
+
 // Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
 // format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
 // in the format returned by ecKeyPairGetPrivateKey()).
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 7f4674d..36ecdb0 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -54,6 +54,7 @@
 #include <keymaster/contexts/pure_soft_keymaster_context.h>
 #include <keymaster/contexts/soft_attestation_cert.h>
 #include <keymaster/keymaster_tags.h>
+#include <keymaster/km_openssl/asymmetric_key.h>
 #include <keymaster/km_openssl/attestation_utils.h>
 #include <keymaster/km_openssl/certificate_utils.h>
 
@@ -168,6 +169,286 @@
 using X509_NAME_Ptr = bssl::UniquePtr<X509_NAME>;
 using X509_EXTENSION_Ptr = bssl::UniquePtr<X509_EXTENSION>;
 
+namespace {
+
+EVP_PKEY_Ptr generateP256Key() {
+    EC_KEY_Ptr ec_key(EC_KEY_new());
+    EVP_PKEY_Ptr pkey(EVP_PKEY_new());
+    EC_GROUP_Ptr group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+
+    if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+
+    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+        LOG(ERROR) << "Error generating key";
+        return {};
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+        LOG(ERROR) << "Error getting private key";
+        return {};
+    }
+
+    return pkey;
+}
+
+optional<vector<uint8_t>> derEncodeKeyPair(const EVP_PKEY& pkey) {
+    int size = i2d_PrivateKey(&pkey, nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return std::nullopt;
+    }
+
+    vector<uint8_t> keyPair(size);
+    unsigned char* p = keyPair.data();
+    i2d_PrivateKey(&pkey, &p);
+
+    return keyPair;
+}
+
+// Extract the issuer subject name from the leaf cert in the given chain,
+// returning it as DER-encoded bytes.
+optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate) {
+    const uint8_t* input = certificate.data();
+    X509_Ptr cert(d2i_X509(/*cert=*/nullptr, &input, certificate.size()));
+    if (!cert) {
+        LOG(ERROR) << "Failed to parse certificate";
+        return std::nullopt;
+    }
+
+    X509_NAME* subject = X509_get_subject_name(cert.get());
+    if (!subject) {
+        LOG(ERROR) << "Failed to retrieve subject name";
+        return std::nullopt;
+    }
+
+    int encodedSubjectLength = i2d_X509_NAME(subject, /*out=*/nullptr);
+    if (encodedSubjectLength < 0) {
+        LOG(ERROR) << "Error obtaining encoded subject name length";
+        return std::nullopt;
+    }
+
+    vector<uint8_t> encodedSubject(encodedSubjectLength);
+    uint8_t* out = encodedSubject.data();
+    if (encodedSubjectLength != i2d_X509_NAME(subject, &out)) {
+        LOG(ERROR) << "Error encoding subject name";
+        return std::nullopt;
+    }
+
+    return encodedSubject;
+}
+
+// Generates the attestation certificate with the parameters passed in.  Note
+// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
+// milli seconds since epoch.  We are setting them to milliseconds due to
+// requirement in AuthorizationSet KM_DATE fields.  The certificate created is
+// actually in seconds.
+//
+optional<vector<vector<uint8_t>>> signAttestationCertificate(
+        const ::keymaster::PureSoftKeymasterContext& context, const EVP_PKEY* key,
+        const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
+        const vector<uint8_t>& attestationKeyBlob,
+        const vector<uint8_t>& derAttestationCertSubjectName, uint64_t activeTimeMilliSeconds,
+        uint64_t expireTimeMilliSeconds, bool isTestCredential) {
+    ::keymaster::X509_NAME_Ptr subjectName;
+    if (KM_ERROR_OK !=
+        ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
+        LOG(ERROR) << "Cannot create attestation subject";
+        return {};
+    }
+
+    vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
+    unsigned char* subjectPtr = subject.data();
+
+    i2d_X509_NAME(subjectName.get(), &subjectPtr);
+
+    ::keymaster::AuthorizationSet auth_set(
+            ::keymaster::AuthorizationSetBuilder()
+                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
+                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
+                    .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
+                                   challenge.size())
+                    .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
+                    // Even though identity attestation hal said the application
+                    // id should be in software enforced authentication set,
+                    // keymaster portable lib expect the input in this
+                    // parameter because the software enforced in input to keymaster
+                    // refers to the key software enforced properties. And this
+                    // parameter refers to properties of the attestation which
+                    // includes app id.
+                    .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
+                                   applicationId.data(), applicationId.size())
+                    .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
+                                   subject.size())
+                    .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
+
+    // Unique id and device id is not applicable for identity credential attestation,
+    // so we don't need to set those or application id.
+    ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
+            ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
+
+    ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
+            ::keymaster::AuthorizationSetBuilder()
+                    .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
+                    .Authorization(::keymaster::TAG_KEY_SIZE, 256)
+                    .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
+                    .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
+                    .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
+                    .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
+                    .Authorization(::keymaster::TAG_OS_VERSION, 42)
+                    .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
+
+    // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
+    if (!isTestCredential) {
+        hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
+    }
+    ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
+
+    keymaster_error_t error;
+    ::keymaster::AttestKeyInfo attestKeyInfo;
+    ::keymaster::KeymasterBlob issuerSubjectNameBlob;
+    if (!attestationKeyBlob.empty()) {
+        ::keymaster::KeymasterKeyBlob blob(attestationKeyBlob.data(), attestationKeyBlob.size());
+        ::keymaster::UniquePtr<::keymaster::Key> parsedKey;
+        error = context.ParseKeyBlob(blob, /*additional_params=*/{}, &parsedKey);
+        if (error != KM_ERROR_OK) {
+            LOG(ERROR) << "Error loading attestation key: " << error;
+            return std::nullopt;
+        }
+
+        attestKeyInfo.signing_key =
+                static_cast<::keymaster::AsymmetricKey&>(*parsedKey).InternalToEvp();
+        issuerSubjectNameBlob = ::keymaster::KeymasterBlob(derAttestationCertSubjectName.data(),
+                                                           derAttestationCertSubjectName.size());
+        attestKeyInfo.issuer_subject = &issuerSubjectNameBlob;
+    }
+
+    ::keymaster::CertificateChain certChain = generate_attestation(
+            key, swEnforced, hwEnforced, auth_set, std::move(attestKeyInfo), context, &error);
+
+    if (KM_ERROR_OK != error) {
+        LOG(ERROR) << "Error generating attestation from EVP key: " << error;
+        return std::nullopt;
+    }
+
+    vector<vector<uint8_t>> vectors(certChain.entry_count);
+    for (std::size_t i = 0; i < certChain.entry_count; i++) {
+        vectors[i] = {certChain.entries[i].data,
+                      certChain.entries[i].data + certChain.entries[i].data_length};
+    }
+    return vectors;
+}
+
+int parseDigits(const char** s, int numDigits) {
+    int result;
+    auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
+    if (ec != std::errc()) {
+        LOG(ERROR) << "Error parsing " << numDigits << " digits "
+                   << " from " << s;
+        return 0;
+    }
+    *s += numDigits;
+    return result;
+}
+
+bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
+    struct tm tm;
+
+    memset(&tm, '\0', sizeof(tm));
+    const char* timeStr = (const char*)asn1Time->data;
+    const char* s = timeStr;
+    if (asn1Time->type == V_ASN1_UTCTIME) {
+        tm.tm_year = parseDigits(&s, 2);
+        if (tm.tm_year < 70) {
+            tm.tm_year += 100;
+        }
+    } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
+        tm.tm_year = parseDigits(&s, 4) - 1900;
+        tm.tm_year -= 1900;
+    } else {
+        LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
+        return false;
+    }
+    tm.tm_mon = parseDigits(&s, 2) - 1;
+    tm.tm_mday = parseDigits(&s, 2);
+    tm.tm_hour = parseDigits(&s, 2);
+    tm.tm_min = parseDigits(&s, 2);
+    tm.tm_sec = parseDigits(&s, 2);
+    // This may need to be updated if someone create certificates using +/- instead of Z.
+    //
+    if (*s != 'Z') {
+        LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
+        return false;
+    }
+
+    time_t t = timegm(&tm);
+    if (t == -1) {
+        LOG(ERROR) << "Error converting broken-down time to time_t";
+        return false;
+    }
+    *outTime = t;
+    return true;
+}
+
+optional<uint64_t> getCertificateExpiryAsMillis(const uint8_t* derCert, size_t derCertSize) {
+    X509_Ptr x509Cert(d2i_X509(nullptr, &derCert, derCertSize));
+    if (!x509Cert) {
+        LOG(ERROR) << "Error parsing certificate";
+        return std::nullopt;
+    }
+
+    time_t notAfter;
+    if (!parseAsn1Time(X509_get0_notAfter(x509Cert.get()), &notAfter)) {
+        LOG(ERROR) << "Error getting notAfter from batch certificate";
+        return std::nullopt;
+    }
+
+    return notAfter * 1000;
+}
+
+optional<vector<vector<uint8_t>>> createAttestation(EVP_PKEY* pkey,
+                                                    const vector<uint8_t>& challenge,
+                                                    const vector<uint8_t>& applicationId,
+                                                    bool isTestCredential) {
+    // Pretend to be implemented in a trusted environment just so we can pass
+    // the VTS tests. Of course, this is a pretend-only game since hopefully no
+    // relying party is ever going to trust our batch key and those keys above
+    // it.
+    ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
+                                                  KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
+
+    keymaster_error_t error;
+    ::keymaster::CertificateChain attestation_chain =
+            context.GetAttestationChain(KM_ALGORITHM_EC, &error);
+    if (KM_ERROR_OK != error) {
+        LOG(ERROR) << "Error getting attestation chain " << error;
+        return std::nullopt;
+    }
+
+    if (attestation_chain.entry_count < 1) {
+        LOG(ERROR) << "Expected at least one entry in attestation chain";
+        return std::nullopt;
+    }
+
+    uint64_t activeTimeMs = time(nullptr) * 1000;
+    optional<uint64_t> expireTimeMs = getCertificateExpiryAsMillis(
+            attestation_chain.entries[0].data, attestation_chain.entries[0].data_length);
+    if (!expireTimeMs) {
+        LOG(ERROR) << "Error getting expiration time for batch cert";
+        return std::nullopt;
+    }
+
+    return signAttestationCertificate(context, pkey, applicationId, challenge,
+                                      /*attestationKeyBlob=*/{},
+                                      /*derAttestationCertSubjectName=*/{}, activeTimeMs,
+                                      *expireTimeMs, isTestCredential);
+}
+
+}  // namespace
+
 // bool getRandom(size_t numBytes, vector<uint8_t>& output) {
 optional<vector<uint8_t>> getRandom(size_t numBytes) {
     vector<uint8_t> output;
@@ -577,69 +858,30 @@
     return hmac;
 }
 
-int parseDigits(const char** s, int numDigits) {
-    int result;
-    auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
-    if (ec != std::errc()) {
-        LOG(ERROR) << "Error parsing " << numDigits << " digits "
-                   << " from " << s;
-        return 0;
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+        bool isTestCredential) {
+    EVP_PKEY_Ptr pkey = generateP256Key();
+
+    optional<vector<vector<uint8_t>>> attestationCertChain =
+            createAttestation(pkey.get(), challenge, applicationId, isTestCredential);
+    if (!attestationCertChain) {
+        LOG(ERROR) << "Error create attestation from key and challenge";
+        return {};
     }
-    *s += numDigits;
-    return result;
+
+    optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
+    if (!keyPair) {
+        return std::nullopt;
+    }
+
+    return make_pair(*keyPair, *attestationCertChain);
 }
 
-bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
-    struct tm tm;
-
-    memset(&tm, '\0', sizeof(tm));
-    const char* timeStr = (const char*)asn1Time->data;
-    const char* s = timeStr;
-    if (asn1Time->type == V_ASN1_UTCTIME) {
-        tm.tm_year = parseDigits(&s, 2);
-        if (tm.tm_year < 70) {
-            tm.tm_year += 100;
-        }
-    } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
-        tm.tm_year = parseDigits(&s, 4) - 1900;
-        tm.tm_year -= 1900;
-    } else {
-        LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
-        return false;
-    }
-    tm.tm_mon = parseDigits(&s, 2) - 1;
-    tm.tm_mday = parseDigits(&s, 2);
-    tm.tm_hour = parseDigits(&s, 2);
-    tm.tm_min = parseDigits(&s, 2);
-    tm.tm_sec = parseDigits(&s, 2);
-    // This may need to be updated if someone create certificates using +/- instead of Z.
-    //
-    if (*s != 'Z') {
-        LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
-        return false;
-    }
-
-    time_t t = timegm(&tm);
-    if (t == -1) {
-        LOG(ERROR) << "Error converting broken-down time to time_t";
-        return false;
-    }
-    *outTime = t;
-    return true;
-}
-
-// Generates the attestation certificate with the parameters passed in.  Note
-// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
-// milli seconds since epoch.  We are setting them to milliseconds due to
-// requirement in AuthorizationSet KM_DATE fields.  The certificate created is
-// actually in seconds.
-//
-// If 0 is passed for expiration time, the expiration time from batch
-// certificate will be used.
-//
-optional<vector<vector<uint8_t>>> createAttestation(
-        const EVP_PKEY* key, const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
-        uint64_t activeTimeMilliSeconds, uint64_t expireTimeMilliSeconds, bool isTestCredential) {
+optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+        const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
+        bool isTestCredential) {
     // Pretend to be implemented in a trusted environment just so we can pass
     // the VTS tests. Of course, this is a pretend-only game since hopefully no
     // relying party is ever going to trust our batch key and those keys above
@@ -647,148 +889,45 @@
     ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
                                                   KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
 
-    keymaster_error_t error;
-    ::keymaster::CertificateChain attestation_chain =
-            context.GetAttestationChain(KM_ALGORITHM_EC, &error);
-    if (KM_ERROR_OK != error) {
-        LOG(ERROR) << "Error getting attestation chain " << error;
-        return {};
-    }
-    if (expireTimeMilliSeconds == 0) {
-        if (attestation_chain.entry_count < 1) {
-            LOG(ERROR) << "Expected at least one entry in attestation chain";
-            return {};
-        }
-        keymaster_blob_t* bcBlob = &(attestation_chain.entries[0]);
-        const uint8_t* bcData = bcBlob->data;
-        auto bc = X509_Ptr(d2i_X509(nullptr, &bcData, bcBlob->data_length));
-        time_t bcNotAfter;
-        if (!parseAsn1Time(X509_get0_notAfter(bc.get()), &bcNotAfter)) {
-            LOG(ERROR) << "Error getting notAfter from batch certificate";
-            return {};
-        }
-        expireTimeMilliSeconds = bcNotAfter * 1000;
+    EVP_PKEY_Ptr pkey = generateP256Key();
+
+    uint64_t validFromMs = time(nullptr) * 1000;
+    optional<uint64_t> notAfterMs =
+            getCertificateExpiryAsMillis(attestationKeyCert.data(), attestationKeyCert.size());
+    if (!notAfterMs) {
+        LOG(ERROR) << "Error getting expiration time for attestation cert";
+        return std::nullopt;
     }
 
-    ::keymaster::X509_NAME_Ptr subjectName;
-    if (KM_ERROR_OK !=
-        ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
-        LOG(ERROR) << "Cannot create attestation subject";
-        return {};
+    optional<vector<uint8_t>> derIssuerSubject =
+            extractDerSubjectFromCertificate(attestationKeyCert);
+    if (!derIssuerSubject) {
+        LOG(ERROR) << "Error error extracting issuer name from the given certificate chain";
+        return std::nullopt;
     }
 
-    vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
-    unsigned char* subjectPtr = subject.data();
-
-    i2d_X509_NAME(subjectName.get(), &subjectPtr);
-
-    ::keymaster::AuthorizationSet auth_set(
-            ::keymaster::AuthorizationSetBuilder()
-                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
-                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
-                    .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
-                                   challenge.size())
-                    .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
-                    // Even though identity attestation hal said the application
-                    // id should be in software enforced authentication set,
-                    // keymaster portable lib expect the input in this
-                    // parameter because the software enforced in input to keymaster
-                    // refers to the key software enforced properties. And this
-                    // parameter refers to properties of the attestation which
-                    // includes app id.
-                    .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
-                                   applicationId.data(), applicationId.size())
-                    .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
-                                   subject.size())
-                    .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
-
-    // Unique id and device id is not applicable for identity credential attestation,
-    // so we don't need to set those or application id.
-    ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
-            ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
-
-    ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
-            ::keymaster::AuthorizationSetBuilder()
-                    .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
-                    .Authorization(::keymaster::TAG_KEY_SIZE, 256)
-                    .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
-                    .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
-                    .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
-                    .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
-                    .Authorization(::keymaster::TAG_OS_VERSION, 42)
-                    .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
-
-    // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
-    if (!isTestCredential) {
-        hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
+    optional<vector<vector<uint8_t>>> attestationCertChain = signAttestationCertificate(
+            context, pkey.get(), applicationId, challenge, attestationKeyBlob, *derIssuerSubject,
+            validFromMs, *notAfterMs, isTestCredential);
+    if (!attestationCertChain) {
+        LOG(ERROR) << "Error signing attestation certificate";
+        return std::nullopt;
     }
-    ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
-
-    ::keymaster::CertificateChain cert_chain_out = generate_attestation(
-            key, swEnforced, hwEnforced, auth_set, {} /* attest_key */, context, &error);
-
-    if (KM_ERROR_OK != error) {
-        LOG(ERROR) << "Error generating attestation from EVP key: " << error;
-        return {};
-    }
-
-    // translate certificate format from keymaster_cert_chain_t to vector<vector<uint8_t>>.
-    vector<vector<uint8_t>> attestationCertificate;
-    for (std::size_t i = 0; i < cert_chain_out.entry_count; i++) {
-        attestationCertificate.insert(
-                attestationCertificate.end(),
-                vector<uint8_t>(
-                        cert_chain_out.entries[i].data,
-                        cert_chain_out.entries[i].data + cert_chain_out.entries[i].data_length));
-    }
-
-    return attestationCertificate;
-}
-
-optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
-        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
-        bool isTestCredential) {
-    auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
-    auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
-    auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
-
-    if (ec_key.get() == nullptr || pkey.get() == nullptr) {
-        LOG(ERROR) << "Memory allocation failed";
-        return {};
-    }
-
-    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
-        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
-        LOG(ERROR) << "Error generating key";
-        return {};
-    }
-
-    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
-        LOG(ERROR) << "Error getting private key";
-        return {};
-    }
-
-    uint64_t nowMs = time(nullptr) * 1000;
-    uint64_t expireTimeMs = 0;  // Set to same as batch certificate
-
-    optional<vector<vector<uint8_t>>> attestationCert = createAttestation(
-            pkey.get(), applicationId, challenge, nowMs, expireTimeMs, isTestCredential);
-    if (!attestationCert) {
+    if (!attestationCertChain) {
         LOG(ERROR) << "Error create attestation from key and challenge";
-        return {};
+        return std::nullopt;
+    }
+    if (attestationCertChain->size() != 1) {
+        LOG(ERROR) << "Expected exactly one attestation cert, got " << attestationCertChain->size();
+        return std::nullopt;
     }
 
-    int size = i2d_PrivateKey(pkey.get(), nullptr);
-    if (size == 0) {
-        LOG(ERROR) << "Error generating public key encoding";
-        return {};
+    optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
+    if (!keyPair) {
+        return std::nullopt;
     }
 
-    vector<uint8_t> keyPair(size);
-    unsigned char* p = keyPair.data();
-    i2d_PrivateKey(pkey.get(), &p);
-
-    return make_pair(keyPair, attestationCert.value());
+    return make_pair(*keyPair, attestationCertChain->at(0));
 }
 
 optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
@@ -820,12 +959,8 @@
         return {};
     }
 
-    uint64_t nowMs = time(nullptr) * 1000;
-    uint64_t expireTimeMs = 0;  // Set to same as batch certificate
-
     optional<vector<vector<uint8_t>>> attestationCert =
-            createAttestation(pkey.get(), applicationId, challenge, nowMs, expireTimeMs,
-                              false /* isTestCredential */);
+            createAttestation(pkey.get(), applicationId, challenge, false /* isTestCredential */);
     if (!attestationCert) {
         LOG(ERROR) << "Error create attestation from key and challenge";
         return {};
@@ -1134,6 +1269,14 @@
         return {};
     }
 
+    return ecPublicKeyGenerateCertificate(pkey.get(), privPkey.get(), serialDecimal, issuer,
+                                          subject, validityNotBefore, validityNotAfter, extensions);
+}
+
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
+        const string& issuer, const string& subject, time_t validityNotBefore,
+        time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions) {
     auto x509 = X509_Ptr(X509_new());
     if (!x509.get()) {
         LOG(ERROR) << "Error creating X509 certificate";
@@ -1145,7 +1288,7 @@
         return {};
     }
 
-    if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+    if (X509_set_pubkey(x509.get(), publicKey) != 1) {
         LOG(ERROR) << "Error setting public key";
         return {};
     }
@@ -1220,7 +1363,7 @@
         }
     }
 
-    if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
+    if (X509_sign(x509.get(), signingKey, EVP_sha256()) == 0) {
         LOG(ERROR) << "Error signing X509 certificate";
         return {};
     }
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index eb28db7..9b897c4 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -967,6 +967,11 @@
 }
 
 nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
+    if (!hal::utils::hasNoPointerData(model)) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+               << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
+    }
+
     return Model{
             .main = NN_TRY(unvalidatedConvert(model.main)),
             .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
@@ -982,6 +987,11 @@
 }
 
 nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
+    if (!hal::utils::hasNoPointerData(request)) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+               << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
+    }
+
     return Request{
             .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
             .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
index ae0d092..c04294a 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
@@ -20,6 +20,7 @@
 #include <nnapi/Result.h>
 #include <nnapi/SharedMemory.h>
 #include <nnapi/Types.h>
+
 #include <functional>
 #include <vector>
 
@@ -47,81 +48,10 @@
         const nn::Capabilities::PerformanceInfo& float32Performance,
         const nn::Capabilities::PerformanceInfo& quantized8Performance);
 
-// Indicates if the object contains no pointer-based data that could be relocated to shared memory.
-bool hasNoPointerData(const nn::Model& model);
-bool hasNoPointerData(const nn::Request& request);
-
-// Relocate pointer-based data to shared memory. If `model` has no Operand::LifeTime::POINTER data,
-// the function returns with a reference to `model`. If `model` has Operand::LifeTime::POINTER data,
-// the model is copied to `maybeModelInSharedOut` with the POINTER data relocated to a memory pool,
-// and the function returns with a reference to `*maybeModelInSharedOut`.
-nn::GeneralResult<std::reference_wrapper<const nn::Model>> flushDataFromPointerToShared(
-        const nn::Model* model, std::optional<nn::Model>* maybeModelInSharedOut);
-
-// Record a relocation mapping between pointer-based data and shared memory.
-// Only two specializations of this template may exist:
-// - RelocationInfo<const void*> for request inputs
-// - RelocationInfo<void*> for request outputs
-template <typename PointerType>
-struct RelocationInfo {
-    PointerType data;
-    size_t length;
-    size_t offset;
-};
-using InputRelocationInfo = RelocationInfo<const void*>;
-using OutputRelocationInfo = RelocationInfo<void*>;
-
-// Keep track of the relocation mapping between pointer-based data and shared memory pool,
-// and provide method to copy the data between pointers and the shared memory pool.
-// Only two specializations of this template may exist:
-// - RelocationTracker<InputRelocationInfo> for request inputs
-// - RelocationTracker<OutputRelocationInfo> for request outputs
-template <typename RelocationInfoType>
-class RelocationTracker {
-  public:
-    static nn::GeneralResult<std::unique_ptr<RelocationTracker>> create(
-            std::vector<RelocationInfoType> relocationInfos, nn::SharedMemory memory) {
-        auto mapping = NN_TRY(map(memory));
-        return std::make_unique<RelocationTracker<RelocationInfoType>>(
-                std::move(relocationInfos), std::move(memory), std::move(mapping));
-    }
-
-    RelocationTracker(std::vector<RelocationInfoType> relocationInfos, nn::SharedMemory memory,
-                      nn::Mapping mapping)
-        : kRelocationInfos(std::move(relocationInfos)),
-          kMemory(std::move(memory)),
-          kMapping(std::move(mapping)) {}
-
-    // Specializations defined in CommonUtils.cpp.
-    // For InputRelocationTracker, this method will copy pointer data to the shared memory pool.
-    // For OutputRelocationTracker, this method will copy shared memory data to the pointers.
-    void flush() const;
-
-  private:
-    const std::vector<RelocationInfoType> kRelocationInfos;
-    const nn::SharedMemory kMemory;
-    const nn::Mapping kMapping;
-};
-using InputRelocationTracker = RelocationTracker<InputRelocationInfo>;
-using OutputRelocationTracker = RelocationTracker<OutputRelocationInfo>;
-
-struct RequestRelocation {
-    std::unique_ptr<InputRelocationTracker> input;
-    std::unique_ptr<OutputRelocationTracker> output;
-};
-
-// Relocate pointer-based data to shared memory. If `request` has no
-// Request::Argument::LifeTime::POINTER data, the function returns with a reference to `request`. If
-// `request` has Request::Argument::LifeTime::POINTER data, the request is copied to
-// `maybeRequestInSharedOut` with the POINTER data relocated to a memory pool, and the function
-// returns with a reference to `*maybeRequestInSharedOut`. The `relocationOut` will be set to track
-// the input and output relocations.
-//
-// Unlike `flushDataFromPointerToShared`, this method will not copy the input pointer data to the
-// shared memory pool. Use `relocationOut` to flush the input or output data after the call.
-nn::GeneralResult<std::reference_wrapper<const nn::Request>> convertRequestFromPointerToShared(
-        const nn::Request* request, uint32_t alignment, uint32_t padding,
-        std::optional<nn::Request>* maybeRequestInSharedOut, RequestRelocation* relocationOut);
+using nn::convertRequestFromPointerToShared;
+using nn::flushDataFromPointerToShared;
+using nn::hasNoPointerData;
+using nn::RequestRelocation;
 
 }  // namespace android::hardware::neuralnetworks::utils
 
diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp
index b249881..dd55add 100644
--- a/neuralnetworks/utils/common/src/CommonUtils.cpp
+++ b/neuralnetworks/utils/common/src/CommonUtils.cpp
@@ -31,59 +31,6 @@
 #include <vector>
 
 namespace android::hardware::neuralnetworks::utils {
-namespace {
-
-bool hasNoPointerData(const nn::Operand& operand);
-bool hasNoPointerData(const nn::Model::Subgraph& subgraph);
-bool hasNoPointerData(const nn::Request::Argument& argument);
-
-template <typename Type>
-bool hasNoPointerData(const std::vector<Type>& objects) {
-    return std::all_of(objects.begin(), objects.end(),
-                       [](const auto& object) { return hasNoPointerData(object); });
-}
-
-bool hasNoPointerData(const nn::DataLocation& location) {
-    return std::visit([](auto ptr) { return ptr == nullptr; }, location.pointer);
-}
-
-bool hasNoPointerData(const nn::Operand& operand) {
-    return hasNoPointerData(operand.location);
-}
-
-bool hasNoPointerData(const nn::Model::Subgraph& subgraph) {
-    return hasNoPointerData(subgraph.operands);
-}
-
-bool hasNoPointerData(const nn::Request::Argument& argument) {
-    return hasNoPointerData(argument.location);
-}
-
-void copyPointersToSharedMemory(nn::Operand* operand, nn::ConstantMemoryBuilder* memoryBuilder) {
-    CHECK(operand != nullptr);
-    CHECK(memoryBuilder != nullptr);
-
-    if (operand->lifetime != nn::Operand::LifeTime::POINTER) {
-        return;
-    }
-
-    const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
-                                  operand->location.pointer);
-    CHECK(data != nullptr);
-    operand->lifetime = nn::Operand::LifeTime::CONSTANT_REFERENCE;
-    operand->location = memoryBuilder->append(data, operand->location.length);
-}
-
-void copyPointersToSharedMemory(nn::Model::Subgraph* subgraph,
-                                nn::ConstantMemoryBuilder* memoryBuilder) {
-    CHECK(subgraph != nullptr);
-    std::for_each(subgraph->operands.begin(), subgraph->operands.end(),
-                  [memoryBuilder](auto& operand) {
-                      copyPointersToSharedMemory(&operand, memoryBuilder);
-                  });
-}
-
-}  // anonymous namespace
 
 nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP(
         const nn::Capabilities::PerformanceInfo& float32Performance,
@@ -104,131 +51,4 @@
             .value();
 }
 
-bool hasNoPointerData(const nn::Model& model) {
-    return hasNoPointerData(model.main) && hasNoPointerData(model.referenced);
-}
-
-bool hasNoPointerData(const nn::Request& request) {
-    return hasNoPointerData(request.inputs) && hasNoPointerData(request.outputs);
-}
-
-nn::GeneralResult<std::reference_wrapper<const nn::Model>> flushDataFromPointerToShared(
-        const nn::Model* model, std::optional<nn::Model>* maybeModelInSharedOut) {
-    CHECK(model != nullptr);
-    CHECK(maybeModelInSharedOut != nullptr);
-
-    if (hasNoPointerData(*model)) {
-        return *model;
-    }
-
-    // Make a copy of the model in order to make modifications. The modified model is returned to
-    // the caller through `maybeModelInSharedOut` if the function succeeds.
-    nn::Model modelInShared = *model;
-
-    nn::ConstantMemoryBuilder memoryBuilder(modelInShared.pools.size());
-    copyPointersToSharedMemory(&modelInShared.main, &memoryBuilder);
-    std::for_each(modelInShared.referenced.begin(), modelInShared.referenced.end(),
-                  [&memoryBuilder](auto& subgraph) {
-                      copyPointersToSharedMemory(&subgraph, &memoryBuilder);
-                  });
-
-    if (!memoryBuilder.empty()) {
-        auto memory = NN_TRY(memoryBuilder.finish());
-        modelInShared.pools.push_back(std::move(memory));
-    }
-
-    *maybeModelInSharedOut = modelInShared;
-    return **maybeModelInSharedOut;
-}
-
-template <>
-void InputRelocationTracker::flush() const {
-    // Copy from pointers to shared memory.
-    uint8_t* memoryPtr = static_cast<uint8_t*>(std::get<void*>(kMapping.pointer));
-    for (const auto& [data, length, offset] : kRelocationInfos) {
-        std::memcpy(memoryPtr + offset, data, length);
-    }
-}
-
-template <>
-void OutputRelocationTracker::flush() const {
-    // Copy from shared memory to pointers.
-    const uint8_t* memoryPtr = static_cast<const uint8_t*>(
-            std::visit([](auto ptr) { return static_cast<const void*>(ptr); }, kMapping.pointer));
-    for (const auto& [data, length, offset] : kRelocationInfos) {
-        std::memcpy(data, memoryPtr + offset, length);
-    }
-}
-
-nn::GeneralResult<std::reference_wrapper<const nn::Request>> convertRequestFromPointerToShared(
-        const nn::Request* request, uint32_t alignment, uint32_t padding,
-        std::optional<nn::Request>* maybeRequestInSharedOut, RequestRelocation* relocationOut) {
-    CHECK(request != nullptr);
-    CHECK(maybeRequestInSharedOut != nullptr);
-    CHECK(relocationOut != nullptr);
-
-    if (hasNoPointerData(*request)) {
-        return *request;
-    }
-
-    // Make a copy of the request in order to make modifications. The modified request is returned
-    // to the caller through `maybeRequestInSharedOut` if the function succeeds.
-    nn::Request requestInShared = *request;
-
-    RequestRelocation relocation;
-
-    // Change input pointers to shared memory.
-    nn::MutableMemoryBuilder inputBuilder(requestInShared.pools.size());
-    std::vector<InputRelocationInfo> inputRelocationInfos;
-    for (auto& input : requestInShared.inputs) {
-        const auto& location = input.location;
-        if (input.lifetime != nn::Request::Argument::LifeTime::POINTER) {
-            continue;
-        }
-
-        input.lifetime = nn::Request::Argument::LifeTime::POOL;
-        const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
-                                      location.pointer);
-        CHECK(data != nullptr);
-        input.location = inputBuilder.append(location.length, alignment, padding);
-        inputRelocationInfos.push_back({data, input.location.length, input.location.offset});
-    }
-
-    // Allocate input memory.
-    if (!inputBuilder.empty()) {
-        auto memory = NN_TRY(inputBuilder.finish());
-        requestInShared.pools.push_back(memory);
-        relocation.input = NN_TRY(
-                InputRelocationTracker::create(std::move(inputRelocationInfos), std::move(memory)));
-    }
-
-    // Change output pointers to shared memory.
-    nn::MutableMemoryBuilder outputBuilder(requestInShared.pools.size());
-    std::vector<OutputRelocationInfo> outputRelocationInfos;
-    for (auto& output : requestInShared.outputs) {
-        const auto& location = output.location;
-        if (output.lifetime != nn::Request::Argument::LifeTime::POINTER) {
-            continue;
-        }
-
-        output.lifetime = nn::Request::Argument::LifeTime::POOL;
-        void* data = std::get<void*>(location.pointer);
-        CHECK(data != nullptr);
-        output.location = outputBuilder.append(location.length, alignment, padding);
-        outputRelocationInfos.push_back({data, output.location.length, output.location.offset});
-    }
-
-    // Allocate output memory.
-    if (!outputBuilder.empty()) {
-        auto memory = NN_TRY(outputBuilder.finish());
-        requestInShared.pools.push_back(memory);
-        relocation.output = NN_TRY(OutputRelocationTracker::create(std::move(outputRelocationInfos),
-                                                                   std::move(memory)));
-    }
-
-    *maybeRequestInSharedOut = requestInShared;
-    *relocationOut = std::move(relocation);
-    return **maybeRequestInSharedOut;
-}
-
 }  // namespace android::hardware::neuralnetworks::utils
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index d390c7e..30365f6 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/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.nfc",
     vendor_available: true,
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
index 907d23d..6daebe5 100644
--- a/nfc/aidl/default/Android.bp
+++ b/nfc/aidl/default/Android.bp
@@ -1,3 +1,12 @@
+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.nfc-service.example",
     relative_install_path: "hw",
diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp
index cd64bca..8d0d782 100644
--- a/radio/1.0/Android.bp
+++ b/radio/1.0/Android.bp
@@ -23,5 +23,9 @@
     interfaces: [
         "android.hidl.base@1.0",
     ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth",
+    ],
     gen_java: true,
 }
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 c8efea0..02bbf21 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
@@ -53,7 +53,7 @@
   boolean preferred;
   boolean persistent;
   boolean alwaysOn;
-  @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
+  android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
   const int ID_DEFAULT = 0;
   const int ID_TETHERED = 1;
   const int ID_IMS = 2;
@@ -62,6 +62,6 @@
   const int ID_OEM_BASE = 1000;
   const int ID_INVALID = -1;
   const int TYPE_COMMON = 0;
-  const int TYPE_THREE_GPP = 1;
-  const int TYPE_THREE_GPP2 = 2;
+  const int TYPE_3GPP = 1;
+  const int TYPE_3GPP2 = 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 dc6092a..7b572f1 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
@@ -44,7 +44,7 @@
   oneway void setDataAllowed(in int serial, in boolean allow);
   oneway void setDataProfile(in int serial, in android.hardware.radio.data.DataProfileInfo[] profiles);
   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 setInitialAttachApn(in int serial, in @nullable 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 boolean matchAllRuleAllowed);
   oneway void startHandover(in int serial, in int callId);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
index b0fc349..dfec59a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -37,7 +37,6 @@
   oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu);
   oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsAck smsAck);
   oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.messaging.SmsAcknowledgeFailCause cause);
-  oneway void cancelPendingUssd(in int serial);
   oneway void deleteSmsOnRuim(in int serial, in int index);
   oneway void deleteSmsOnSim(in int serial, in int index);
   oneway void getCdmaBroadcastConfig(in int serial);
@@ -50,7 +49,6 @@
   oneway void sendImsSms(in int serial, in android.hardware.radio.messaging.ImsSmsMessage message);
   oneway void sendSms(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
   oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
-  oneway void sendUssd(in int serial, in String ussd);
   oneway void setCdmaBroadcastActivation(in int serial, in boolean activate);
   oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo);
   oneway void setGsmBroadcastActivation(in int serial, in boolean activate);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index 89a0f3b..8f7824f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -40,6 +40,5 @@
   oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
   oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber);
   oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
-  oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.UssdModeType modeType, in String msg);
   oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 156f24b..c3af7a6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -38,7 +38,6 @@
   oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void acknowledgeRequest(in int serial);
-  oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs);
@@ -50,7 +49,6 @@
   oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
   oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
   oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
-  oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index ef9c779..85cf86e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -36,6 +36,5 @@
 parcelable CarrierRestrictions {
   android.hardware.radio.sim.Carrier[] allowedCarriers;
   android.hardware.radio.sim.Carrier[] excludedCarriers;
-  boolean priority;
   boolean allowedCarriersPrioritized;
 }
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 34d155a..603b1d6 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
@@ -35,6 +35,7 @@
 @VintfStability
 interface IRadioVoice {
   oneway void acceptCall(in int serial);
+  oneway void cancelPendingUssd(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 int categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
@@ -59,6 +60,7 @@
   oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
   oneway void sendCdmaFeatureCode(in int serial, in String featureCode);
   oneway void sendDtmf(in int serial, in String s);
+  oneway void sendUssd(in int serial, in String ussd);
   oneway void separateConnection(in int serial, in int gsmIndex);
   oneway void setCallForward(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
   oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index af3417d..189ed43 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -44,6 +44,7 @@
   oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
   oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start);
   oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.StkCcUnsolSsResult ss);
+  oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.UssdModeType modeType, in String msg);
   oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type);
   oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.SrvccState state);
   oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index a3b5e58..7acc044 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -36,6 +36,7 @@
 interface IRadioVoiceResponse {
   oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void acknowledgeRequest(in int serial);
+  oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info);
@@ -59,6 +60,7 @@
   oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
similarity index 97%
rename from radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl
rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
index 5395b11..9a9d723 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
@@ -31,7 +31,7 @@
 // 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.messaging;
+package android.hardware.radio.voice;
 @Backing(type="int") @VintfStability
 enum UssdModeType {
   NOTIFY = 0,
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 7360202..123b3ed 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -16,9 +16,7 @@
 
 package android.hardware.radio.data;
 
-import android.hardware.radio.RadioAccessFamily;
 import android.hardware.radio.data.ApnAuthType;
-import android.hardware.radio.data.ApnTypes;
 import android.hardware.radio.data.PdpProtocolType;
 import android.hardware.radio.data.TrafficDescriptor;
 
@@ -36,8 +34,8 @@
     const int ID_INVALID = 0xFFFFFFFF;
 
     const int TYPE_COMMON = 0;
-    const int TYPE_THREE_GPP = 1;
-    const int TYPE_THREE_GPP2 = 2;
+    const int TYPE_3GPP = 1;
+    const int TYPE_3GPP2 = 2;
 
     /**
      * ID of the data profile.
@@ -130,5 +128,5 @@
      * 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;
+    TrafficDescriptor trafficDescriptor;
 }
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 54a045c..e1ba568 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -159,14 +159,15 @@
             in long completionDurationMillis);
 
     /**
-     * Set an APN to initial attach network.
+     * Set an APN to initial attach network or clear the existing initial attach APN.
      *
      * @param serial Serial number of request.
-     * @param dataProfileInfo data profile containing APN settings
+     * @param dataProfileInfo Data profile containing APN settings or null to clear the existing
+     *        initial attach APN.
      *
      * Response function is IRadioDataResponse.setInitialAttachApnResponse()
      */
-    void setInitialAttachApn(in int serial, in DataProfileInfo dataProfileInfo);
+    void setInitialAttachApn(in int serial, in @nullable DataProfileInfo dataProfileInfo);
 
     /**
      * Set response functions for data radio requests and indications.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
index 1dbaed3..8bd84a3 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -79,15 +79,6 @@
             in int serial, in boolean success, in SmsAcknowledgeFailCause cause);
 
     /**
-     * Cancel the current USSD session if one exists.
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioMessagingResponse.cancelPendingUssdResponse()
-     */
-    void cancelPendingUssd(in int serial);
-
-    /**
      * Deletes a CDMA SMS message from RUIM memory.
      *
      * @param serial Serial number of request.
@@ -212,23 +203,6 @@
     void sendSmsExpectMore(in int serial, in GsmSmsMessage message);
 
     /**
-     * Send a USSD message. If a USSD session already exists, the message must be sent in the
-     * context of that session. Otherwise, a new session must be created. The network reply must be
-     * reported via unsolOnUssd.
-     *
-     * Only one USSD session must exist at a time, and the session is assumed to exist until:
-     * a) The android system invokes cancelUssd()
-     * b) The implementation sends a unsolOnUssd() with a type code of
-     *    "0" (USSD-Notify/no further action) or "2" (session terminated)
-     *
-     * @param serial Serial number of request.
-     * @param ussd string containing the USSD request in UTF-8 format
-     *
-     * Response function is IRadioMessagingResponse.sendUssdResponse()
-     */
-    void sendUssd(in int serial, in String ussd);
-
-    /**
      * Enable or disable the reception of CDMA Cell Broadcast SMS
      *
      * @param serial Serial number of request.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index 4b40bfb..8834cd9 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -18,7 +18,6 @@
 
 import android.hardware.radio.RadioIndicationType;
 import android.hardware.radio.messaging.CdmaSmsMessage;
-import android.hardware.radio.messaging.UssdModeType;
 
 /**
  * Interface declaring unsolicited radio indications for messaging APIs.
@@ -86,16 +85,6 @@
     void newSmsStatusReport(in RadioIndicationType type, in byte[] pdu);
 
     /**
-     * Indicates when a new USSD message is received. The USSD session is assumed to persist if the
-     * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
-     *
-     * @param type Type of radio indication
-     * @param modeType USSD type code
-     * @param msg Message string in UTF-8, if applicable
-     */
-    void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg);
-
-    /**
      * Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a
      * new SMS message. Messages cannot be saved on the SIM until space is freed. In particular,
      * incoming Class 2 messages must not be stored.
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 75fa390..492755f 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -92,27 +92,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:SIM_BUSY
-     *   RadioError:OPERATION_NOT_ALLOWED
-     *   RadioError:MODEM_ERR
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_MEMORY
-     *   RadioError:INVALID_STATE
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     */
-    void cancelPendingUssdResponse(in RadioResponseInfo info);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
@@ -407,32 +386,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:USSD_MODIFIED_TO_DIAL
-     *   RadioError:USSD_MODIFIED_TO_SS
-     *   RadioError:USSD_MODIFIED_TO_USSD
-     *   RadioError:SIM_BUSY
-     *   RadioError:OPERATION_NOT_ALLOWED
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:NO_MEMORY
-     *   RadioError:MODEM_ERR
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:ABORTED
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     */
-    void sendUssdResponse(in RadioResponseInfo info);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_STATE
      *   RadioError:NO_MEMORY
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index 9bd5f21..96b9d0d 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -16,8 +16,6 @@
 
 package android.hardware.radio.modem;
 
-import android.hardware.radio.RadioAccessFamily;
-
 @VintfStability
 parcelable RadioCapability {
     /**
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 7a22a9a..cce52ff 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -17,7 +17,6 @@
 package android.hardware.radio.network;
 
 import android.hardware.radio.AccessNetwork;
-import android.hardware.radio.RadioAccessFamily;
 import android.hardware.radio.network.CdmaRoamingType;
 import android.hardware.radio.network.IRadioNetworkIndication;
 import android.hardware.radio.network.IRadioNetworkResponse;
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 6863ac3..f471433 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -21,7 +21,6 @@
 import android.hardware.radio.network.BarringInfo;
 import android.hardware.radio.network.CellIdentity;
 import android.hardware.radio.network.CellInfo;
-import android.hardware.radio.network.Domain;
 import android.hardware.radio.network.LinkCapacityEstimate;
 import android.hardware.radio.network.NetworkScanResult;
 import android.hardware.radio.network.PhoneRestrictedState;
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index e650321..dcf0004 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -16,7 +16,6 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.RadioAccessFamily;
 import android.hardware.radio.RadioResponseInfo;
 import android.hardware.radio.RadioTechnology;
 import android.hardware.radio.RadioTechnologyFamily;
@@ -24,8 +23,6 @@
 import android.hardware.radio.network.CdmaRoamingType;
 import android.hardware.radio.network.CellIdentity;
 import android.hardware.radio.network.CellInfo;
-import android.hardware.radio.network.LceDataInfo;
-import android.hardware.radio.network.NeighboringCell;
 import android.hardware.radio.network.OperatorInfo;
 import android.hardware.radio.network.RadioAccessSpecifier;
 import android.hardware.radio.network.RadioBandMode;
diff --git a/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl b/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl
deleted file mode 100644
index 270bdee..0000000
--- a/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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;
-
-@VintfStability
-parcelable NeighboringCell {
-    /**
-     * Combination of LAC and cell ID in 32 bits in GSM. Upper 16 bits is LAC and lower 16 bits is
-     * CID (as described in TS 27.005).
-     */
-    String cid;
-    /**
-     * Received RSSI in GSM, level index of CPICH Received Signal Code Power in UMTS
-     */
-    int rssi;
-}
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index 12df138..ef38fdc 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -31,11 +31,6 @@
      */
     Carrier[] excludedCarriers;
     /**
-     * Whether this is a carrier restriction with priority or not.
-     * If this is false, allowedCarriersPrioritized is not applicable.
-     */
-    boolean priority;
-    /**
      * True means that only carriers included in the allowed list and not in the excluded list
      * are permitted. Eg. allowedCarriers match mcc/mnc, excludedCarriers has same mcc/mnc and
      * gid1 is ABCD. It means except the carrier whose gid1 is ABCD, all carriers with the
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index ddc5d76..9fed78e 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -16,8 +16,6 @@
 
 package android.hardware.radio.voice;
 
-import android.hardware.radio.voice.EmergencyServiceCategory;
-
 /**
  * Emergency number contains information of number, one or more service category(s), zero or more
  * emergency uniform resource names, mobile country code (mcc), mobile network country (mnc) and
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index b25e63d..c05d237 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -19,7 +19,6 @@
 import android.hardware.radio.voice.CallForwardInfo;
 import android.hardware.radio.voice.Dial;
 import android.hardware.radio.voice.EmergencyCallRouting;
-import android.hardware.radio.voice.EmergencyServiceCategory;
 import android.hardware.radio.voice.IRadioVoiceIndication;
 import android.hardware.radio.voice.IRadioVoiceResponse;
 import android.hardware.radio.voice.TtyMode;
@@ -45,6 +44,15 @@
     void acceptCall(in int serial);
 
     /**
+     * Cancel the current USSD session if one exists.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response function is IRadioVoiceResponse.cancelPendingUssdResponse()
+     */
+    void cancelPendingUssd(in int serial);
+
+    /**
      * Conference holding and active (like AT+CHLD=3)
      *
      * @param serial Serial number of request.
@@ -325,6 +333,23 @@
     void sendDtmf(in int serial, in String s);
 
     /**
+     * Send a USSD message. If a USSD session already exists, the message must be sent in the
+     * context of that session. Otherwise, a new session must be created. The network reply must be
+     * reported via unsolOnUssd.
+     *
+     * Only one USSD session must exist at a time, and the session is assumed to exist until:
+     * a) The android system invokes cancelUssd()
+     * b) The implementation sends a unsolOnUssd() with a type code of
+     *    "0" (USSD-Notify/no further action) or "2" (session terminated)
+     *
+     * @param serial Serial number of request.
+     * @param ussd string containing the USSD request in UTF-8 format
+     *
+     * Response function is IRadioVoiceResponse.sendUssdResponse()
+     */
+    void sendUssd(in int serial, in String ussd);
+
+    /**
      * Separate a party from a multiparty call placing the multiparty call (less the specified
      * party) on hold and leaving the specified party as the only other member of the current
      * (active) call. Like AT+CHLD=2x.
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 25e87b3..437fef6 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -24,6 +24,7 @@
 import android.hardware.radio.voice.EmergencyNumber;
 import android.hardware.radio.voice.SrvccState;
 import android.hardware.radio.voice.StkCcUnsolSsResult;
+import android.hardware.radio.voice.UssdModeType;
 
 /**
  * Interface declaring unsolicited radio indications for voice APIs.
@@ -138,6 +139,16 @@
     void onSupplementaryServiceIndication(in RadioIndicationType type, in StkCcUnsolSsResult ss);
 
     /**
+     * Indicates when a new USSD message is received. The USSD session is assumed to persist if the
+     * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
+     *
+     * @param type Type of radio indication
+     * @param modeType USSD type code
+     * @param msg Message string in UTF-8, if applicable
+     */
+    void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg);
+
+    /**
      * Indicates that framework/application must reset the uplink mute state.
      *
      * @param type Type of radio indication
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index d126fc1..cf1b953 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -62,6 +62,27 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:SIM_BUSY
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:INVALID_STATE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     */
+    void cancelPendingUssdResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:NO_MEMORY
      *   RadioError:MODEM_ERR
@@ -569,6 +590,32 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:FDN_CHECK_FAILURE
+     *   RadioError:USSD_MODIFIED_TO_DIAL
+     *   RadioError:USSD_MODIFIED_TO_SS
+     *   RadioError:USSD_MODIFIED_TO_USSD
+     *   RadioError:SIM_BUSY
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_MEMORY
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:ABORTED
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:INVALID_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     */
+    void sendUssdResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_STATE
      *   RadioError:NO_RESOURCES
diff --git a/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
similarity index 95%
rename from radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl
rename to radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
index c3c111e..48d1fca 100644
--- a/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl
+++ b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.messaging;
+package android.hardware.radio.voice;
 
 @VintfStability
 @Backing(type="int")
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
index d2f3687..51f5543 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioData.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -122,9 +122,10 @@
     return ok();
 }
 
-ScopedAStatus RadioData::setInitialAttachApn(int32_t serial, const aidl::DataProfileInfo& info) {
+ScopedAStatus RadioData::setInitialAttachApn(int32_t serial,
+                                             const std::optional<aidl::DataProfileInfo>& info) {
     LOG_CALL << serial;
-    mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info));
+    mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info.value()));
     return ok();
 }
 
@@ -136,14 +137,15 @@
     return ok();
 }
 
-ScopedAStatus RadioData::setupDataCall(  //
-        int32_t serial, aidlCommon::AccessNetwork accessNetwork,
-        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, bool matchAllRuleAllowed) {
+ScopedAStatus RadioData::setupDataCall(int32_t serial, aidlCommon::AccessNetwork accessNetwork,
+                                       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,
+                                       bool matchAllRuleAllowed) {
     if (mHal1_6) {
-        mHal1_6->setupDataCall_1_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),
@@ -151,7 +153,7 @@
                 matchAllRuleAllowed);
         mContext->addDataProfile(dataProfileInfo);
     } else {
-        mHal1_5->setupDataCall_1_5(  //
+        mHal1_5->setupDataCall_1_5(
                 serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
                 V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses));
     }
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
index c617ec2..c2c0de3 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -44,7 +44,8 @@
             int64_t completionDurationMillis) override;
     ::ndk::ScopedAStatus setInitialAttachApn(
             int32_t serial,
-            const ::aidl::android::hardware::radio::data::DataProfileInfo& dpInfo) override;
+            const std::optional<::aidl::android::hardware::radio::data::DataProfileInfo>& dpInfo)
+            override;
     ::ndk::ScopedAStatus setResponseFunctions(
             const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse>&
                     radioDataResponse,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
index 419e9fb..047f836 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -33,7 +33,6 @@
     ::ndk::ScopedAStatus acknowledgeLastIncomingGsmSms(
             int32_t serial, bool success,
             ::aidl::android::hardware::radio::messaging::SmsAcknowledgeFailCause cause) override;
-    ::ndk::ScopedAStatus cancelPendingUssd(int32_t serial) override;
     ::ndk::ScopedAStatus deleteSmsOnRuim(int32_t serial, int32_t index) override;
     ::ndk::ScopedAStatus deleteSmsOnSim(int32_t serial, int32_t index) override;
     ::ndk::ScopedAStatus getCdmaBroadcastConfig(int32_t serial) override;
@@ -56,7 +55,6 @@
     ::ndk::ScopedAStatus sendSmsExpectMore(
             int32_t serial,
             const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
-    ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
     ::ndk::ScopedAStatus setCdmaBroadcastActivation(int32_t serial, bool activate) override;
     ::ndk::ScopedAStatus setCdmaBroadcastConfig(
             int32_t serial,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
index a0e1e82..0f1d5fd 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -26,6 +26,7 @@
     std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> respond();
 
     ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
+    ::ndk::ScopedAStatus cancelPendingUssd(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;
@@ -58,6 +59,7 @@
                                        int32_t off) override;
     ::ndk::ScopedAStatus sendCdmaFeatureCode(int32_t serial, const std::string& fcode) override;
     ::ndk::ScopedAStatus sendDtmf(int32_t serial, const std::string& s) override;
+    ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
     ::ndk::ScopedAStatus separateConnection(int32_t serial, int32_t gsmIndex) override;
     ::ndk::ScopedAStatus setCallForward(
             int32_t serial,
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
index e5c33b3..eb87828 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -73,13 +73,6 @@
     return {};
 }
 
-Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
-                                     const hidl_string& msg) {
-    LOG_CALL << type;
-    messagingCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
-    return {};
-}
-
 Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
     messagingCb()->simSmsStorageFull(toAidl(type));
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
index 4d94e17..56d49f1 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -54,12 +54,6 @@
     return ok();
 }
 
-ScopedAStatus RadioMessaging::cancelPendingUssd(int32_t serial) {
-    LOG_CALL << serial;
-    mHal1_5->cancelPendingUssd(serial);
-    return ok();
-}
-
 ScopedAStatus RadioMessaging::deleteSmsOnRuim(int32_t serial, int32_t index) {
     LOG_CALL << serial << ' ' << index;
     mHal1_5->deleteSmsOnRuim(serial, index);
@@ -148,12 +142,6 @@
     return ok();
 }
 
-ScopedAStatus RadioMessaging::sendUssd(int32_t serial, const std::string& ussd) {
-    LOG_CALL << serial << ' ' << ussd;
-    mHal1_5->sendUssd(serial, ussd);
-    return ok();
-}
-
 ScopedAStatus RadioMessaging::setCdmaBroadcastActivation(int32_t serial, bool activate) {
     LOG_CALL << serial << ' ' << activate;
     mHal1_5->setCdmaBroadcastActivation(serial, activate);
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
index 24ad3d7..7a9273f 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -57,12 +57,6 @@
     return {};
 }
 
-Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
-    LOG_CALL << info.serial;
-    messagingCb()->cancelPendingUssdResponse(toAidl(info));
-    return {};
-}
-
 Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
     messagingCb()->deleteSmsOnRuimResponse(toAidl(info));
@@ -166,12 +160,6 @@
     return {};
 }
 
-Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
-    LOG_CALL << info.serial;
-    messagingCb()->sendUssdResponse(toAidl(info));
-    return {};
-}
-
 Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
index 87a021f..c1d9b35 100644
--- a/radio/aidl/compat/libradiocompat/network/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -650,13 +650,6 @@
     };
 }
 
-aidl::NeighboringCell toAidl(const V1_0::NeighboringCell& cell) {
-    return {
-            .cid = cell.cid,
-            .rssi = cell.rssi,
-    };
-}
-
 aidl::LceDataInfo toAidl(const V1_0::LceDataInfo& info) {
     return {
             .lastHopCapacityKbps = static_cast<int32_t>(info.lastHopCapacityKbps),
diff --git a/radio/aidl/compat/libradiocompat/network/structs.h b/radio/aidl/compat/libradiocompat/network/structs.h
index 854cb38..aaa49a0 100644
--- a/radio/aidl/compat/libradiocompat/network/structs.h
+++ b/radio/aidl/compat/libradiocompat/network/structs.h
@@ -20,7 +20,6 @@
 #include <aidl/android/hardware/radio/network/CellInfo.h>
 #include <aidl/android/hardware/radio/network/LceDataInfo.h>
 #include <aidl/android/hardware/radio/network/LinkCapacityEstimate.h>
-#include <aidl/android/hardware/radio/network/NeighboringCell.h>
 #include <aidl/android/hardware/radio/network/NetworkScanRequest.h>
 #include <aidl/android/hardware/radio/network/NetworkScanResult.h>
 #include <aidl/android/hardware/radio/network/OperatorInfo.h>
@@ -92,8 +91,6 @@
 ::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_5::RegStateResult& res);
 ::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_6::RegStateResult& res);
 
-::aidl::android::hardware::radio::network::NeighboringCell toAidl(const V1_0::NeighboringCell& c);
-
 ::aidl::android::hardware::radio::network::LceDataInfo toAidl(const V1_0::LceDataInfo& info);
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
index 359fce0..23878ed 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -102,6 +102,13 @@
     return {};
 }
 
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                                     const hidl_string& msg) {
+    LOG_CALL << type;
+    voiceCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+    return {};
+}
+
 Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
     voiceCb()->resendIncallMute(toAidl(type));
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
index d233548..5307e11 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -42,6 +42,12 @@
     return {};
 }
 
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    voiceCb()->cancelPendingUssdResponse(toAidl(info));
+    return {};
+}
+
 Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
     voiceCb()->conferenceResponse(toAidl(info));
@@ -198,6 +204,12 @@
     return {};
 }
 
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    voiceCb()->sendUssdResponse(toAidl(info));
+    return {};
+}
+
 Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
     voiceCb()->separateConnectionResponse(toAidl(info));
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
index 71d1a56..9088f01 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -40,6 +40,12 @@
     return ok();
 }
 
+ScopedAStatus RadioVoice::cancelPendingUssd(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->cancelPendingUssd(serial);
+    return ok();
+}
+
 ScopedAStatus RadioVoice::conference(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->conference(serial);
@@ -201,6 +207,12 @@
     return ok();
 }
 
+ScopedAStatus RadioVoice::sendUssd(int32_t serial, const std::string& ussd) {
+    LOG_CALL << serial << ' ' << ussd;
+    mHal1_5->sendUssd(serial, ussd);
+    return ok();
+}
+
 ScopedAStatus RadioVoice::separateConnection(int32_t serial, int32_t gsmIndex) {
     LOG_CALL << serial;
     mHal1_5->separateConnection(serial, gsmIndex);
diff --git a/radio/aidl/vts/OWNERS b/radio/aidl/vts/OWNERS
new file mode 100644
index 0000000..e75c6c8
--- /dev/null
+++ b/radio/aidl/vts/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 20868
+include ../../1.0/vts/OWNERS
+
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index 1a152fb..8d81605 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -19,12 +19,15 @@
 RadioConfigResponse::RadioConfigResponse(RadioServiceTest& parent) : parent_config(parent) {}
 
 ndk::ScopedAStatus RadioConfigResponse::getSimSlotsStatusResponse(
-        const RadioResponseInfo& /* info */, const std::vector<SimSlotStatus>& /* slotStatus */) {
+        const RadioResponseInfo& info, const std::vector<SimSlotStatus>& /* slotStatus */) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(
-        const RadioResponseInfo& /* info */) {
+ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -37,22 +40,28 @@
 }
 
 ndk::ScopedAStatus RadioConfigResponse::setPreferredDataModemResponse(
-        const RadioResponseInfo& /* info */) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioConfigResponse::getNumOfLiveModemsResponse(
-        const RadioResponseInfo& /* info */, const int8_t /* numOfLiveModems */) {
+        const RadioResponseInfo& info, const int8_t /* numOfLiveModems */) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(
-        const RadioResponseInfo& /* info */) {
+ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioConfigResponse::getHalDeviceCapabilitiesResponse(
         const RadioResponseInfo& info, bool modemReducedFeatures) {
+    rspInfo = info;
     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
index 2d7fe01..a271b8a 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -54,3 +54,102 @@
     ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
           toString(radioRsp_config->rspInfo.error).c_str());
 }
+
+/*
+ * Test IRadioConfig.getSimSlotsStatus() for the response returned.
+ */
+TEST_P(RadioConfigTest, getSimSlotsStatus) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
+    ASSERT_OK(res);
+    ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+}
+
+/*
+ * Test IRadioConfig.getPhoneCapability() for the response returned.
+ */
+TEST_P(RadioConfigTest, getPhoneCapability) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    ALOGI("getPhoneCapability, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_config->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+    if (radioRsp_config->rspInfo.error == RadioError ::NONE) {
+        // maxActiveData should be greater than or equal to maxActiveInternetData.
+        EXPECT_GE(radioRsp_config->phoneCap.maxActiveData,
+                  radioRsp_config->phoneCap.maxActiveInternetData);
+        // maxActiveData and maxActiveInternetData should be 0 or positive numbers.
+        EXPECT_GE(radioRsp_config->phoneCap.maxActiveInternetData, 0);
+    }
+}
+
+/*
+ * Test IRadioConfig.setPreferredDataModem() for the response returned.
+ */
+TEST_P(RadioConfigTest, setPreferredDataModem) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    ALOGI("getPhoneCapability, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_config->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+    if (radioRsp_config->rspInfo.error != RadioError ::NONE) {
+        return;
+    }
+
+    if (radioRsp_config->phoneCap.logicalModemIds.size() == 0) {
+        return;
+    }
+
+    // We get phoneCapability. Send setPreferredDataModem command
+    serial = GetRandomSerialNumber();
+    uint8_t modemId = radioRsp_config->phoneCap.logicalModemIds[0];
+    res = radio_config->setPreferredDataModem(serial, modemId);
+
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_config->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+}
+
+/*
+ * Test IRadioConfig.setPreferredDataModem() with invalid arguments.
+ */
+TEST_P(RadioConfigTest, setPreferredDataModem_invalidArgument) {
+    serial = GetRandomSerialNumber();
+    uint8_t modemId = -1;
+    ndk::ScopedAStatus res = radio_config->setPreferredDataModem(serial, modemId);
+
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error,
+                                 {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::INTERNAL_ERR}));
+}
diff --git a/radio/aidl/vts/radio_data_response.cpp b/radio/aidl/vts/radio_data_response.cpp
index 9b17bfb..8d51760 100644
--- a/radio/aidl/vts/radio_data_response.cpp
+++ b/radio/aidl/vts/radio_data_response.cpp
@@ -36,8 +36,9 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -61,11 +62,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -75,8 +80,9 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -94,11 +100,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& info,
                                                              const KeepaliveStatus& /*status*/) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
index 8547e9d..f38a958 100644
--- a/radio/aidl/vts/radio_data_test.cpp
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -83,7 +83,7 @@
     dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
     dataProfileInfo.user = std::string("username");
     dataProfileInfo.password = std::string("password");
-    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
     dataProfileInfo.maxConnsTime = 300;
     dataProfileInfo.maxConns = 20;
     dataProfileInfo.waitTime = 0;
@@ -157,7 +157,7 @@
     dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
     dataProfileInfo.user = std::string("username");
     dataProfileInfo.password = std::string("password");
-    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
     dataProfileInfo.maxConnsTime = 300;
     dataProfileInfo.maxConns = 20;
     dataProfileInfo.waitTime = 0;
@@ -309,3 +309,280 @@
 
     sleep(1);
 }
+
+/*
+ * Test IRadioData.setInitialAttachApn() for the response returned.
+ */
+TEST_P(RadioDataTest, setInitialAttachApn) {
+    serial = GetRandomSerialNumber();
+
+    // Create a dataProfileInfo
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+
+    radio_data->setInitialAttachApn(serial, dataProfileInfo);
+
+    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}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+    }
+}
+
+/*
+ * Test IRadioData.setDataProfile() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataProfile) {
+    serial = GetRandomSerialNumber();
+
+    // Create a dataProfileInfo
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_3GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = true;
+
+    // Create a dataProfileInfoList
+    std::vector<DataProfileInfo> dataProfileInfoList = {dataProfileInfo};
+
+    radio_data->setDataProfile(serial, dataProfileInfoList);
+
+    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}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+    }
+}
+
+/*
+ * Test IRadioData.deactivateDataCall() for the response returned.
+ */
+TEST_P(RadioDataTest, deactivateDataCall) {
+    serial = GetRandomSerialNumber();
+    int cid = 1;
+    DataRequestReason reason = DataRequestReason::NORMAL;
+
+    ndk::ScopedAStatus res = radio_data->deactivateDataCall(serial, cid, reason);
+    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::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::INVALID_CALL_ID, RadioError::INVALID_STATE,
+                                  RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED,
+                                  RadioError::CANCELLED, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_data->rspInfo.error,
+                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+                 RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+                 RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED}));
+    }
+}
+
+/*
+ * Test IRadioData.startKeepalive() for the response returned.
+ */
+TEST_P(RadioDataTest, startKeepalive) {
+    std::vector<KeepaliveRequest> requests = {
+            {
+                    // Invalid IPv4 source address
+                    KeepaliveRequest::TYPE_NATT_IPV4,
+                    {192, 168, 0 /*, 100*/},
+                    1234,
+                    {8, 8, 4, 4},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid IPv4 destination address
+                    KeepaliveRequest::TYPE_NATT_IPV4,
+                    {192, 168, 0, 100},
+                    1234,
+                    {8, 8, 4, 4, 1, 2, 3, 4},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid Keepalive Type
+                    -1,
+                    {192, 168, 0, 100},
+                    1234,
+                    {8, 8, 4, 4},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid IPv6 source address
+                    KeepaliveRequest::TYPE_NATT_IPV6,
+                    {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+                     0xED, 0xBE, 0xEF, 0xBD},
+                    1234,
+                    {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x88, 0x44},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid IPv6 destination address
+                    KeepaliveRequest::TYPE_NATT_IPV6,
+                    {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+                     0xED, 0xBE, 0xEF},
+                    1234,
+                    {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x88,
+                     /*0x44*/},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid Context ID (cid), this should survive the initial
+                    // range checking and fail in the modem data layer
+                    KeepaliveRequest::TYPE_NATT_IPV4,
+                    {192, 168, 0, 100},
+                    1234,
+                    {8, 8, 4, 4},
+                    4500,
+                    20000,
+                    0xBAD,
+            },
+            {
+                    // Invalid Context ID (cid), this should survive the initial
+                    // range checking and fail in the modem data layer
+                    KeepaliveRequest::TYPE_NATT_IPV6,
+                    {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+                     0xED, 0xBE, 0xEF},
+                    1234,
+                    {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x88, 0x44},
+                    4500,
+                    20000,
+                    0xBAD,
+            }};
+
+    for (auto req = requests.begin(); req != requests.end(); req++) {
+        serial = GetRandomSerialNumber();
+        radio_data->startKeepalive(serial, *req);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_data->rspInfo.error,
+                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+                 RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioData.stopKeepalive() for the response returned.
+ */
+TEST_P(RadioDataTest, stopKeepalive) {
+    serial = GetRandomSerialNumber();
+
+    radio_data->stopKeepalive(serial, 0xBAD);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                              RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioData.getDataCallList() for the response returned.
+ */
+TEST_P(RadioDataTest, getDataCallList) {
+    LOG(DEBUG) << "getDataCallList";
+    serial = GetRandomSerialNumber();
+
+    radio_data->getDataCallList(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 (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_data->rspInfo.error,
+                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT}));
+    }
+    LOG(DEBUG) << "getDataCallList finished";
+}
+
+/*
+ * Test IRadioData.setDataAllowed() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataAllowed) {
+    LOG(DEBUG) << "setDataAllowed";
+    serial = GetRandomSerialNumber();
+    bool allow = true;
+
+    radio_data->setDataAllowed(serial, allow);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_data->rspInfo.error);
+    }
+    LOG(DEBUG) << "setDataAllowed finished";
+}
diff --git a/radio/aidl/vts/radio_messaging_indication.cpp b/radio/aidl/vts/radio_messaging_indication.cpp
index c69611f..481239e 100644
--- a/radio/aidl/vts/radio_messaging_indication.cpp
+++ b/radio/aidl/vts/radio_messaging_indication.cpp
@@ -48,12 +48,6 @@
     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
index 718df7e..49c0806 100644
--- a/radio/aidl/vts/radio_messaging_response.cpp
+++ b/radio/aidl/vts/radio_messaging_response.cpp
@@ -20,17 +20,23 @@
     : parent_messaging(parent) {}
 
 ndk::ScopedAStatus RadioMessagingResponse::acknowledgeIncomingGsmSmsWithPduResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingCdmaSmsResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingGsmSmsResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -38,40 +44,43 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::cancelPendingUssdResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(
-        const RadioResponseInfo& /*info*/) {
-    return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::getCdmaBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/,
-        const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+        const RadioResponseInfo& info, const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::getGsmBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/,
-        const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+        const RadioResponseInfo& info, const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& info,
                                                                   const std::string& /*smsc*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::reportSmsMemoryStatusResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -91,8 +100,10 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& info,
                                                               const SendSmsResult& /*sms*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -112,41 +123,50 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::sendUssdResponse(const RadioResponseInfo& /*info*/) {
-    return ndk::ScopedAStatus::ok();
-}
-
 ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastActivationResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastActivationResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& info,
                                                                   int32_t /*index*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& info,
                                                                  int32_t /*index*/) {
+    rspInfo = info;
+    parent_messaging.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 8abd91d..9f1718b 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -197,3 +197,535 @@
                 CHECK_GENERAL_ERROR));
     }
 }
+
+/*
+ * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
+    LOG(DEBUG) << "setGsmBroadcastConfig";
+    serial = GetRandomSerialNumber();
+
+    // Create GsmBroadcastSmsConfigInfo #1
+    GsmBroadcastSmsConfigInfo gbSmsConfig1;
+    gbSmsConfig1.fromServiceId = 4352;
+    gbSmsConfig1.toServiceId = 4354;
+    gbSmsConfig1.fromCodeScheme = 0;
+    gbSmsConfig1.toCodeScheme = 255;
+    gbSmsConfig1.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #2
+    GsmBroadcastSmsConfigInfo gbSmsConfig2;
+    gbSmsConfig2.fromServiceId = 4356;
+    gbSmsConfig2.toServiceId = 4356;
+    gbSmsConfig2.fromCodeScheme = 0;
+    gbSmsConfig2.toCodeScheme = 255;
+    gbSmsConfig2.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #3
+    GsmBroadcastSmsConfigInfo gbSmsConfig3;
+    gbSmsConfig3.fromServiceId = 4370;
+    gbSmsConfig3.toServiceId = 4379;
+    gbSmsConfig3.fromCodeScheme = 0;
+    gbSmsConfig3.toCodeScheme = 255;
+    gbSmsConfig3.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #4
+    GsmBroadcastSmsConfigInfo gbSmsConfig4;
+    gbSmsConfig4.fromServiceId = 4383;
+    gbSmsConfig4.toServiceId = 4391;
+    gbSmsConfig4.fromCodeScheme = 0;
+    gbSmsConfig4.toCodeScheme = 255;
+    gbSmsConfig4.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #5
+    GsmBroadcastSmsConfigInfo gbSmsConfig5;
+    gbSmsConfig5.fromServiceId = 4392;
+    gbSmsConfig5.toServiceId = 4392;
+    gbSmsConfig5.fromCodeScheme = 0;
+    gbSmsConfig5.toCodeScheme = 255;
+    gbSmsConfig5.selected = true;
+
+    std::vector<GsmBroadcastSmsConfigInfo> gsmBroadcastSmsConfigsInfoList = {
+            gbSmsConfig1, gbSmsConfig2, gbSmsConfig3, gbSmsConfig4, gbSmsConfig5};
+
+    radio_messaging->setGsmBroadcastConfig(serial, gsmBroadcastSmsConfigsInfoList);
+
+    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::NONE, RadioError::INVALID_ARGUMENTS,
+                                      RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setGsmBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.getGsmBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getGsmBroadcastConfig) {
+    LOG(DEBUG) << "getGsmBroadcastConfig";
+    serial = GetRandomSerialNumber();
+
+    radio_messaging->getGsmBroadcastConfig(serial);
+
+    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::NONE, RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getGsmBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
+    LOG(DEBUG) << "setCdmaBroadcastConfig";
+    serial = GetRandomSerialNumber();
+
+    CdmaBroadcastSmsConfigInfo cbSmsConfig;
+    cbSmsConfig.serviceCategory = 4096;
+    cbSmsConfig.language = 1;
+    cbSmsConfig.selected = true;
+
+    std::vector<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList = {cbSmsConfig};
+
+    radio_messaging->setCdmaBroadcastConfig(serial, cdmaBroadcastSmsConfigInfoList);
+
+    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::NONE, RadioError::INVALID_MODEM_STATE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setCdmaBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
+    LOG(DEBUG) << "getCdmaBroadcastConfig";
+    serial = GetRandomSerialNumber();
+
+    radio_messaging->getCdmaBroadcastConfig(serial);
+
+    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::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getCdmaBroadcastConfig finished";
+}
+
+/*
+ * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
+    LOG(DEBUG) << "setCdmaBroadcastActivation";
+    serial = GetRandomSerialNumber();
+    bool activate = false;
+
+    radio_messaging->setCdmaBroadcastActivation(serial, activate);
+
+    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::NONE, RadioError::INVALID_ARGUMENTS},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setCdmaBroadcastActivation finished";
+}
+
+/*
+ * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
+    LOG(DEBUG) << "setGsmBroadcastActivation";
+    serial = GetRandomSerialNumber();
+    bool activate = false;
+
+    radio_messaging->setGsmBroadcastActivation(serial, activate);
+
+    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::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
+                 RadioError::INVALID_STATE, RadioError::OPERATION_NOT_ALLOWED},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setGsmBroadcastActivation finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeLastIncomingGsmSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) {
+    LOG(DEBUG) << "acknowledgeLastIncomingGsmSms";
+    serial = GetRandomSerialNumber();
+    bool success = true;
+
+    radio_messaging->acknowledgeLastIncomingGsmSms(
+            serial, success, SmsAcknowledgeFailCause::MEMORY_CAPACITY_EXCEEDED);
+
+    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},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "acknowledgeLastIncomingGsmSms finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) {
+    LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu";
+    serial = GetRandomSerialNumber();
+    bool success = true;
+    std::string ackPdu = "";
+
+    radio_messaging->acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
+
+    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::NO_SMS_TO_ACK},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu finished";
+}
+
+/*
+ * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
+    LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms";
+    serial = GetRandomSerialNumber();
+
+    // Create a CdmaSmsAck
+    CdmaSmsAck cdmaSmsAck;
+    cdmaSmsAck.errorClass = false;
+    cdmaSmsAck.smsCauseCode = 1;
+
+    radio_messaging->acknowledgeLastIncomingCdmaSms(serial, cdmaSmsAck);
+
+    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::NO_SMS_TO_ACK},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendImsSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendImsSms) {
+    LOG(DEBUG) << "sendImsSms";
+    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};
+
+    // Creata an ImsSmsMessage
+    ImsSmsMessage msg;
+    msg.tech = RadioTechnologyFamily::THREE_GPP2;
+    msg.retry = false;
+    msg.messageRef = 0;
+    msg.cdmaMessage = (std::vector<CdmaSmsMessage>){cdmaSmsMessage};
+    msg.gsmMessage = (std::vector<GsmSmsMessage>){};
+
+    radio_messaging->sendImsSms(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}, CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendImsSms finished";
+}
+
+/*
+ * Test IRadioMessaging.getSmscAddress() for the response returned.
+ */
+TEST_P(RadioMessagingTest, getSmscAddress) {
+    LOG(DEBUG) << "getSmscAddress";
+    serial = GetRandomSerialNumber();
+
+    radio_messaging->getSmscAddress(serial);
+
+    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_MODEM_STATE, RadioError::INVALID_STATE,
+                                      RadioError::SIM_ABSENT},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getSmscAddress finished";
+}
+
+/*
+ * Test IRadioMessaging.setSmscAddress() for the response returned.
+ */
+TEST_P(RadioMessagingTest, setSmscAddress) {
+    LOG(DEBUG) << "setSmscAddress";
+    serial = GetRandomSerialNumber();
+    std::string address = std::string("smscAddress");
+
+    radio_messaging->setSmscAddress(serial, address);
+
+    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_SMS_FORMAT,
+                                      RadioError::SIM_ABSENT},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setSmscAddress finished";
+}
+
+/*
+ * Test IRadioMessaging.writeSmsToSim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, writeSmsToSim) {
+    LOG(DEBUG) << "writeSmsToSim";
+    serial = GetRandomSerialNumber();
+    SmsWriteArgs smsWriteArgs;
+    smsWriteArgs.status = SmsWriteArgs::STATUS_REC_UNREAD;
+    smsWriteArgs.smsc = "";
+    smsWriteArgs.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+    radio_messaging->writeSmsToSim(serial, smsWriteArgs);
+
+    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::NONE, RadioError::ENCODING_ERR, RadioError::INVALID_ARGUMENTS,
+                 RadioError::INVALID_SMSC_ADDRESS, RadioError::MODEM_ERR,
+                 RadioError::NETWORK_NOT_READY, RadioError::NO_RESOURCES, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "writeSmsToSim finished";
+}
+
+/*
+ * Test IRadioMessaging.deleteSmsOnSim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, deleteSmsOnSim) {
+    LOG(DEBUG) << "deleteSmsOnSim";
+    serial = GetRandomSerialNumber();
+    int index = 1;
+
+    radio_messaging->deleteSmsOnSim(serial, index);
+
+    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::NONE, RadioError::ENCODING_ERR, RadioError::INVALID_ARGUMENTS,
+                 RadioError::INVALID_MODEM_STATE, RadioError::NO_SUCH_ENTRY, RadioError::MODEM_ERR,
+                 RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "deleteSmsOnSim finished";
+}
+
+/*
+ * Test IRadioMessaging.writeSmsToRuim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, writeSmsToRuim) {
+    LOG(DEBUG) << "writeSmsToRuim";
+    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};
+
+    // Create a CdmaSmsWriteArgs
+    CdmaSmsWriteArgs cdmaSmsWriteArgs;
+    cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
+    cdmaSmsWriteArgs.message = cdmaSmsMessage;
+
+    radio_messaging->writeSmsToRuim(serial, cdmaSmsWriteArgs);
+
+    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::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT,
+                 RadioError::INVALID_SMSC_ADDRESS, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
+                 RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "writeSmsToRuim finished";
+}
+
+/*
+ * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
+ */
+TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
+    LOG(DEBUG) << "deleteSmsOnRuim";
+    serial = GetRandomSerialNumber();
+    int index = 1;
+
+    // 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};
+
+    // Create a CdmaSmsWriteArgs
+    CdmaSmsWriteArgs cdmaSmsWriteArgs;
+    cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
+    cdmaSmsWriteArgs.message = cdmaSmsMessage;
+
+    radio_messaging->deleteSmsOnRuim(serial, index);
+
+    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::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
+                 RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "deleteSmsOnRuim finished";
+}
+
+/*
+ * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
+ */
+TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
+    LOG(DEBUG) << "reportSmsMemoryStatus";
+    serial = GetRandomSerialNumber();
+    bool available = true;
+
+    radio_messaging->reportSmsMemoryStatus(serial, available);
+
+    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::MODEM_ERR, RadioError::SIM_ABSENT},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "reportSmsMemoryStatus finished";
+}
diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h
index 7bb99cd..7b66192 100644
--- a/radio/aidl/vts/radio_messaging_utils.h
+++ b/radio/aidl/vts/radio_messaging_utils.h
@@ -49,8 +49,6 @@
 
     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;
@@ -84,8 +82,6 @@
     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;
 
@@ -132,9 +128,6 @@
     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;
 };
 
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index 53bfab4..d2715a8 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -22,70 +22,99 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& info,
                                                                   const std::string& /*version*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& info,
                                                                  const std::string& /*imei*/,
                                                                  const std::string& /*imeisv*/,
                                                                  const std::string& /*esn*/,
                                                                  const std::string& /*meid*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
-        const RadioResponseInfo& /*info*/, const std::vector<HardwareConfig>& /*config*/) {
+        const RadioResponseInfo& info, const std::vector<HardwareConfig>& /*config*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioModemResponse::getModemActivityInfoResponse(
-        const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+        const RadioResponseInfo& info, const ActivityStatsInfo& /*activityInfo*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(
-        const RadioResponseInfo& /*info*/, const bool /*enabled*/) {
+ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(const RadioResponseInfo& info,
+                                                                   const bool enabled) {
+    rspInfo = info;
+    isModemEnabled = enabled;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& info,
                                                                   const RadioCapability& /*rc*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& info,
                                                           const std::string& /*result*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& info,
                                                                   const RadioCapability& /*rc*/) {
+    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
index b40bb7b..f88da13 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -87,3 +87,301 @@
     EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
 }
+
+/*
+ * Test IRadioModem.enableModem() for the response returned.
+ */
+TEST_P(RadioModemTest, enableModem) {
+    serial = GetRandomSerialNumber();
+
+    if (isSsSsEnabled()) {
+        ALOGI("enableModem, no need to test in single SIM mode");
+        return;
+    }
+
+    bool responseToggle = radioRsp_modem->enableModemResponseToggle;
+    ndk::ScopedAStatus res = radio_modem->enableModem(serial, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+          toString(radioRsp_modem->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
+
+    // checking if getModemStackStatus returns true, as modem was enabled above
+    if (RadioError::NONE == radioRsp_modem->rspInfo.error) {
+        // wait until modem enabling is finished
+        while (responseToggle == radioRsp_modem->enableModemResponseToggle) {
+            sleep(1);
+        }
+        ndk::ScopedAStatus resEnabled = radio_modem->getModemStackStatus(serial);
+        ASSERT_OK(resEnabled);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+        ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+              toString(radioRsp_modem->rspInfo.error).c_str());
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
+        // verify that enableModem did set isEnabled correctly
+        EXPECT_EQ(true, radioRsp_modem->isModemEnabled);
+    }
+}
+
+/*
+ * Test IRadioModem.getModemStackStatus() for the response returned.
+ */
+TEST_P(RadioModemTest, getModemStackStatus) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_modem->getModemStackStatus(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    ALOGI("getModemStackStatus, rspInfo.error = %s\n",
+          toString(radioRsp_modem->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_modem->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+}
+
+/*
+ * Test IRadioModem.getBasebandVersion() for the response returned.
+ */
+TEST_P(RadioModemTest, getBasebandVersion) {
+    LOG(DEBUG) << "getBasebandVersion";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getBasebandVersion(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+    }
+    LOG(DEBUG) << "getBasebandVersion finished";
+}
+
+/*
+ * Test IRadioModem.getDeviceIdentity() for the response returned.
+ */
+TEST_P(RadioModemTest, getDeviceIdentity) {
+    LOG(DEBUG) << "getDeviceIdentity";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getDeviceIdentity(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::EMPTY_RECORD}));
+    }
+    LOG(DEBUG) << "getDeviceIdentity finished";
+}
+
+/*
+ * Test IRadioModem.nvReadItem() for the response returned.
+ */
+TEST_P(RadioModemTest, nvReadItem) {
+    LOG(DEBUG) << "nvReadItem";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "nvReadItem finished";
+}
+
+/*
+ * Test IRadioModem.nvWriteItem() for the response returned.
+ */
+TEST_P(RadioModemTest, nvWriteItem) {
+    LOG(DEBUG) << "nvWriteItem";
+    serial = GetRandomSerialNumber();
+    NvWriteItem item;
+    memset(&item, 0, sizeof(item));
+    item.value = std::string();
+
+    radio_modem->nvWriteItem(serial, item);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "nvWriteItem finished";
+}
+
+/*
+ * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
+ */
+TEST_P(RadioModemTest, nvWriteCdmaPrl) {
+    LOG(DEBUG) << "nvWriteCdmaPrl";
+    serial = GetRandomSerialNumber();
+    std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
+
+    radio_modem->nvWriteCdmaPrl(serial, std::vector<uint8_t>(prl));
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "nvWriteCdmaPrl finished";
+}
+
+/*
+ * Test IRadioModem.nvResetConfig() for the response returned.
+ */
+TEST_P(RadioModemTest, nvResetConfig) {
+    LOG(DEBUG) << "nvResetConfig";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->nvResetConfig(serial, ResetNvType::FACTORY_RESET);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "nvResetConfig finished";
+}
+
+/*
+ * Test IRadioModem.getHardwareConfig() for the response returned.
+ */
+TEST_P(RadioModemTest, getHardwareConfig) {
+    LOG(DEBUG) << "getHardwareConfig";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getHardwareConfig(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getHardwareConfig finished";
+}
+
+/*
+ * The following test is disabled due to b/64734869
+ *
+ * Test IRadioModem.requestShutdown() for the response returned.
+ */
+TEST_P(RadioModemTest, DISABLED_requestShutdown) {
+    serial = GetRandomSerialNumber();
+
+    radio_modem->requestShutdown(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioModem.getRadioCapability() for the response returned.
+ */
+TEST_P(RadioModemTest, getRadioCapability) {
+    LOG(DEBUG) << "getRadioCapability";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getRadioCapability(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+    }
+    LOG(DEBUG) << "getRadioCapability finished";
+}
+
+/*
+ * Test IRadioModem.setRadioCapability() for the response returned.
+ */
+TEST_P(RadioModemTest, setRadioCapability) {
+    LOG(DEBUG) << "setRadioCapability";
+    serial = GetRandomSerialNumber();
+    RadioCapability rc;
+    memset(&rc, 0, sizeof(rc));
+    rc.logicalModemUuid = std::string();
+
+    radio_modem->setRadioCapability(serial, rc);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setRadioCapability finished";
+}
+
+/*
+ * Test IRadioModem.getModemActivityInfo() for the response returned.
+ */
+TEST_P(RadioModemTest, getModemActivityInfo) {
+    LOG(DEBUG) << "getModemActivityInfo";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getModemActivityInfo(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "getModemActivityInfo finished";
+}
+
+/*
+ * Test IRadioModem.sendDeviceState() for the response returned.
+ */
+TEST_P(RadioModemTest, sendDeviceState) {
+    LOG(DEBUG) << "sendDeviceState";
+    serial = GetRandomSerialNumber();
+
+    radio_modem->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    std::cout << static_cast<int>(radioRsp_modem->rspInfo.error) << std::endl;
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "sendDeviceState finished";
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 9df1db4..666d617 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -31,7 +31,10 @@
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getAvailableBandModesResponse(
-        const RadioResponseInfo& /*info*/, const std::vector<RadioBandMode>& /*bandModes*/) {
+        const RadioResponseInfo& info, const std::vector<RadioBandMode>& bandModes) {
+    rspInfo = info;
+    radioBandModes = bandModes;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -44,48 +47,64 @@
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getBarringInfoResponse(
-        const RadioResponseInfo& /*info*/, const CellIdentity& /*cellIdentity*/,
-        const std::vector<BarringInfo>& /*barringInfos*/) {
+        const RadioResponseInfo& info, const CellIdentity& cellIdentity,
+        const std::vector<BarringInfo>& barringInfos) {
+    rspInfo = info;
+    barringCellIdentity = cellIdentity;
+    barringInfoList = barringInfos;
+    parent_network.notify(info.serial);
     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*/) {
+        const RadioResponseInfo& info, CdmaRoamingType /*type*/) {
     rspInfo = info;
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus RadioNetworkResponse::getCellInfoListResponse(
+        const RadioResponseInfo& info, const std::vector<CellInfo>& /*cellInfo*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getDataRegistrationStateResponse(
+        const RadioResponseInfo& info, const RegStateResult& regResponse) {
+    rspInfo = info;
+    dataRegResp = regResponse;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus RadioNetworkResponse::getImsRegistrationStateResponse(
-        const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
-        RadioTechnologyFamily /*ratFamily*/) {
+        const RadioResponseInfo& info, bool /*isRegistered*/, RadioTechnologyFamily /*ratFamily*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getNetworkSelectionModeResponse(
-        const RadioResponseInfo& /*info*/, bool /*manual*/) {
+        const RadioResponseInfo& info, bool /*manual*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& info,
                                                              const std::string& /*longName*/,
                                                              const std::string& /*shortName*/,
                                                              const std::string& /*numeric*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getSignalStrengthResponse(
-        const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+        const RadioResponseInfo& info, const SignalStrength& /*sig_strength*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -96,20 +115,25 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(
-        const RadioResponseInfo& /*info*/, const UsageSetting /*usageSetting*/) {
+ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(const RadioResponseInfo& info,
+                                                                 const UsageSetting usageSetting) {
+    rspInfo = info;
+    this->usageSetting = usageSetting;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getVoiceRadioTechnologyResponse(
-        const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+        const RadioResponseInfo& info, RadioTechnology /*rat*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getVoiceRegistrationStateResponse(
         const RadioResponseInfo& info, const RegStateResult& regResponse) {
     rspInfo = info;
-    voiceRegResp.regState = regResponse.regState;
+    voiceRegResp = regResponse;
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
@@ -129,47 +153,63 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setCdmaRoamingPreferenceResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setCellInfoListRateResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setIndicationFilterResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setLinkCapacityReportingCriteriaResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeAutomaticResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeManualResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -181,36 +221,47 @@
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setSignalStrengthReportingCriteriaResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setSuppServiceNotificationsResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::setSystemSelectionChannelsResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::supplyNetworkDepersonalizationResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+        const RadioResponseInfo& info, int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 64d8eec..e1d508d 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -16,6 +16,7 @@
 
 #include <aidl/android/hardware/radio/RadioAccessFamily.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/network/IndicationFilter.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 
@@ -58,6 +59,12 @@
     ASSERT_NE(nullptr, radio_config.get());
 }
 
+void RadioNetworkTest::stopNetworkScan() {
+    serial = GetRandomSerialNumber();
+    radio_network->stopNetworkScan(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
 /*
  * Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned.
  */
@@ -152,4 +159,1578 @@
                 radioRsp_network->rspInfo.error,
                 {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR, RadioError::NONE}));
     }
-}
\ No newline at end of file
+}
+
+void RadioNetworkTest::invokeAndExpectResponse(
+        std::function<ndk::ScopedAStatus(int32_t serial)> request,
+        std::vector<RadioError> errors_to_check) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = request(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);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, errors_to_check));
+}
+
+/*
+ * Test IRadioNetwork.getUsageSetting()
+ *
+ * Verify that the usage setting can be retrieved.
+ */
+TEST_P(RadioNetworkTest, getUsageSetting) {
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+                             RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+    ASSERT_TRUE(radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC ||
+                radioRsp_network->usageSetting == UsageSetting::DATA_CENTRIC);
+}
+
+void RadioNetworkTest::testSetUsageSetting_InvalidValues(std::vector<RadioError> errors) {
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial,
+                                                      UsageSetting(0) /*below valid range*/);
+            },
+            errors);
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial, UsageSetting(-1) /*negative*/);
+            },
+            errors);
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial,
+                                                      UsageSetting(3) /*above valid range*/);
+            },
+            errors);
+}
+
+/*
+ * Test IRadioNetwork.setUsageSetting() and IRadioNetwork.getUsageSetting()
+ *
+ * Verify the following:
+ * -That the usage setting can be retrieved.
+ * -That the usage setting can be successfully set to allowed values.
+ * -That the usage setting cannot be set to invalid values.
+ */
+TEST_P(RadioNetworkTest, setUsageSetting) {
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+                             RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+    if (radioRsp_network->rspInfo.error != RadioError::NONE) {
+        // Test only for invalid values, with the only allowable response being the same error
+        // that was previously provided, or an error indicating invalid arguments.
+        testSetUsageSetting_InvalidValues(
+                {radioRsp_network->rspInfo.error, RadioError::INVALID_ARGUMENTS});
+        // It is unsafe to proceed with setting valid values without knowing the starting value, but
+        // we expect errors anyway, so not necessary.
+        return;
+    } else {
+        // Because querying succeeded, the device is in a valid state to test for invalid values
+        // and the only thing that can change is that we expect to have an EINVAL return each time.
+        testSetUsageSetting_InvalidValues({RadioError::INVALID_ARGUMENTS});
+    }
+
+    // Store the original setting value to reset later.
+    const UsageSetting originalSetting = radioRsp_network->usageSetting;
+
+    // Choose the "other" value that is not the current value for test.
+    const UsageSetting testSetting = radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC
+                                             ? UsageSetting::DATA_CENTRIC
+                                             : UsageSetting::VOICE_CENTRIC;
+
+    // Set an alternative setting; it may either succeed or be disallowed as out of range for
+    // the current device (if the device only supports its current mode).
+    invokeAndExpectResponse(
+            [&](int serial) { return radio_network->setUsageSetting(serial, testSetting); },
+            {RadioError::INVALID_ARGUMENTS, RadioError::NONE});
+
+    // If there was no error, then we expect the test setting to be set, or if there is an error
+    // we expect the original setting to be maintained.
+    const UsageSetting expectedSetting =
+            radioRsp_network->rspInfo.error == RadioError::NONE ? testSetting : originalSetting;
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::NONE});
+
+    const UsageSetting updatedSetting = radioRsp_network->usageSetting;
+
+    // Re-set the original setting, which must always succeed.
+    invokeAndExpectResponse(
+            [&](int serial) { return radio_network->setUsageSetting(serial, originalSetting); },
+            {RadioError::NONE});
+
+    // After resetting the value to its original value, update the local cache, which must
+    // always succeed.
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::NONE});
+
+    // Check that indeed the updated setting was set. We do this after resetting to original
+    // conditions to avoid early-exiting the test and leaving the device in a modified state.
+    EXPECT_EQ(expectedSetting, updatedSetting);
+    // Check that indeed the original setting was reset.
+    EXPECT_EQ(originalSetting, radioRsp_network->usageSetting);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() with invalid hysteresisDb
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 10;  // hysteresisDb too large given threshold list deltas
+    signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_invalidHysteresisDb, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() with empty thresholds
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_EmptyThresholds) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfo.hysteresisMs = 0;
+    signalThresholdInfo.hysteresisDb = 0;
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_EmptyParams, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for GERAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Geran) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::GERAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_Geran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSCP;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-110, -97, -73, -49, -25};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::UTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_Utran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRP) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRP;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-128, -108, -88, -68};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_Eutran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRQ) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRQ;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-27, -20, -13, -6};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_Eutran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSSNR) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSNR;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for CDMA2000
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Cdma2000) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::CDMA2000;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_Cdma2000, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRP
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRP) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 0;
+    signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSRSRP, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+    // setSignalStrengthReportingCriteria()
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRQ
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRQ) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRQ;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 0;
+    signalThresholdInfo.thresholds = {-43, -20, 0, 20};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSRSRQ, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+    // setSignalStrengthReportingCriteria()
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Disable_RSSNR) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSNR;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+    signalThresholdInfo.isEnabled = false;
+    signalThresholdInfo.ran = AccessNetwork::EUTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+}
+
+/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSSINR
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSSINR) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSSINR;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 0;
+    signalThresholdInfo.thresholds = {-10, 3, 16, 18};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::NGRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    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);
+
+    ALOGI("setSignalStrengthReportingCriteria_NGRAN_SSSINR, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+    // setSignalStrengthReportingCriteria()
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+            serial, 5000,
+            5000,  // hysteresisDlKbps too big for thresholds delta
+            100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, AccessNetwork::GERAN);
+    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);
+
+    ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+    // for GERAN
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                             {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+            serial, 5000, 500, 1000,  // hysteresisUlKbps too big for thresholds delta
+            {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, AccessNetwork::GERAN);
+    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);
+
+    ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+    // for GERAN
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                             {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() empty params
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_emptyParams) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+            serial, 0, 0, 0, {}, {}, AccessNetwork::GERAN);
+    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);
+
+    ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+    // for GERAN
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setLinkCapacityReportingCriteria() for GERAN
+ */
+TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_Geran) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->setLinkCapacityReportingCriteria(
+            serial, 5000, 500, 100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000},
+            AccessNetwork::GERAN);
+    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);
+
+    ALOGI("setLinkCapacityReportingCriteria_Geran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    // Allow REQUEST_NOT_SUPPORTED as setLinkCapacityReportingCriteria() may not be supported
+    // for GERAN
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSystemSelectionChannels() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSystemSelectionChannels) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    ndk::ScopedAStatus res =
+            radio_network->setSystemSelectionChannels(serial, true, {specifierP900, specifier850});
+    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);
+    ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_network->setSystemSelectionChannels(
+                serial, false, {specifierP900, specifier850});
+        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);
+        ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+              toString(radioRsp_network->rspInfo.error).c_str());
+        EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, startNetworkScan) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 60,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 1};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::SIM_ABSENT}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
+        // not support the required manual GSM search functionality. This is
+        // tracked in b/112206766. Modems have "GSM" rat scan need to
+        // support scanning requests combined with some parameters.
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+    }
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        ALOGI("Stop Network Scan");
+        stopNetworkScan();
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid specifier.
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidArgument) {
+    serial = GetRandomSerialNumber();
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT, .interval = 60};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid interval (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 4,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 60,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 1};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid interval (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 301,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 60,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 1};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid max search time (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 59,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 1};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid max search time (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 3601,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 1};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid periodicity (lower boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 600,
+                                  .incrementalResults = true,
+                                  .incrementalResultsPeriodicity = 0};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with invalid periodicity (upper boundary).
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 600,
+                                  .incrementalResults = true,
+                                  .incrementalResultsPeriodicity = 11};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with valid periodicity
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 360,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 10};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                      RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        ALOGI("Stop Network Scan");
+        stopNetworkScan();
+    }
+}
+
+/*
+ * Test IRadioNetwork.startNetworkScan() with valid periodicity and plmns
+ */
+TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifierBands bandP900 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_P900});
+    RadioAccessSpecifierBands band850 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
+                    {GeranBands::BAND_850});
+    RadioAccessSpecifier specifierP900 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
+    RadioAccessSpecifier specifier850 = {
+            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+                                  .interval = 60,
+                                  .specifiers = {specifierP900, specifier850},
+                                  .maxSearchTime = 360,
+                                  .incrementalResults = false,
+                                  .incrementalResultsPeriodicity = 10,
+                                  .mccMncs = {"310410"}};
+
+    ndk::ScopedAStatus res = radio_network->startNetworkScan(serial, request);
+    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);
+    ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                      RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        ALOGI("Stop Network Scan");
+        stopNetworkScan();
+    }
+}
+
+/*
+ * Test IRadioNetwork.setNetworkSelectionModeManual() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNetworkSelectionModeManual) {
+    serial = GetRandomSerialNumber();
+
+    // can't camp on nonexistent MCCMNC, so we expect this to fail.
+    ndk::ScopedAStatus res =
+            radio_network->setNetworkSelectionModeManual(serial, "123456", AccessNetwork::GERAN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
+                                      RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioNetwork.getBarringInfo() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getBarringInfo) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_network->getBarringInfo(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(radioRsp_network->barringInfoList.size() > 0);
+
+    std::set<int> reportedServices;
+
+    // validate that the service types are in range
+    for (const auto& info : radioRsp_network->barringInfoList) {
+        ASSERT_TRUE((info.serviceType >= BarringInfo::SERVICE_TYPE_CS_SERVICE &&
+                     info.serviceType <= BarringInfo::SERVICE_TYPE_SMS) ||
+                    (info.serviceType >= BarringInfo::SERVICE_TYPE_OPERATOR_1 &&
+                     info.serviceType <= BarringInfo::SERVICE_TYPE_OPERATOR_32));
+        reportedServices.insert(info.serviceType);
+
+        // Any type that is "conditional" must have valid values for conditional barring
+        // factor and time.
+        switch (info.barringType) {
+            case BarringInfo::BARRING_TYPE_NONE:  // fall through
+            case BarringInfo::BARRING_TYPE_UNCONDITIONAL:
+                break;
+            case BarringInfo::BARRING_TYPE_CONDITIONAL: {
+                const int32_t barringFactor = info.barringTypeSpecificInfo->factor;
+                ASSERT_TRUE(barringFactor >= 0 && barringFactor <= 100);
+                ASSERT_TRUE(info.barringTypeSpecificInfo->timeSeconds > 0);
+                break;
+            }
+            default:
+                FAIL();
+        }
+    }
+
+    // Certain types of barring are relevant for certain RANs. Ensure that only the right
+    // types are reported. Note that no types are required, simply that for a given technology
+    // only certain types are valid. This is one way to check that implementations are
+    // not providing information that they don't have.
+    static const std::set<int> UTRA_SERVICES{
+            BarringInfo::SERVICE_TYPE_CS_SERVICE, BarringInfo::SERVICE_TYPE_PS_SERVICE,
+            BarringInfo::SERVICE_TYPE_CS_VOICE,   BarringInfo::SERVICE_TYPE_EMERGENCY,
+            BarringInfo::SERVICE_TYPE_SMS,
+    };
+
+    static const std::set<int> EUTRA_SERVICES{
+            BarringInfo::SERVICE_TYPE_MO_SIGNALLING, BarringInfo::SERVICE_TYPE_MO_DATA,
+            BarringInfo::SERVICE_TYPE_CS_FALLBACK,   BarringInfo::SERVICE_TYPE_MMTEL_VOICE,
+            BarringInfo::SERVICE_TYPE_MMTEL_VIDEO,   BarringInfo::SERVICE_TYPE_EMERGENCY,
+            BarringInfo::SERVICE_TYPE_SMS,
+    };
+
+    static const std::set<int> NGRA_SERVICES = {
+            BarringInfo::SERVICE_TYPE_MO_SIGNALLING, BarringInfo::SERVICE_TYPE_MO_DATA,
+            BarringInfo::SERVICE_TYPE_CS_FALLBACK,   BarringInfo::SERVICE_TYPE_MMTEL_VOICE,
+            BarringInfo::SERVICE_TYPE_MMTEL_VIDEO,   BarringInfo::SERVICE_TYPE_EMERGENCY,
+            BarringInfo::SERVICE_TYPE_SMS,           BarringInfo::SERVICE_TYPE_OPERATOR_1,
+            BarringInfo::SERVICE_TYPE_OPERATOR_2,    BarringInfo::SERVICE_TYPE_OPERATOR_3,
+            BarringInfo::SERVICE_TYPE_OPERATOR_4,    BarringInfo::SERVICE_TYPE_OPERATOR_5,
+            BarringInfo::SERVICE_TYPE_OPERATOR_6,    BarringInfo::SERVICE_TYPE_OPERATOR_7,
+            BarringInfo::SERVICE_TYPE_OPERATOR_8,    BarringInfo::SERVICE_TYPE_OPERATOR_9,
+            BarringInfo::SERVICE_TYPE_OPERATOR_10,   BarringInfo::SERVICE_TYPE_OPERATOR_11,
+            BarringInfo::SERVICE_TYPE_OPERATOR_12,   BarringInfo::SERVICE_TYPE_OPERATOR_13,
+            BarringInfo::SERVICE_TYPE_OPERATOR_14,   BarringInfo::SERVICE_TYPE_OPERATOR_15,
+            BarringInfo::SERVICE_TYPE_OPERATOR_16,   BarringInfo::SERVICE_TYPE_OPERATOR_17,
+            BarringInfo::SERVICE_TYPE_OPERATOR_18,   BarringInfo::SERVICE_TYPE_OPERATOR_19,
+            BarringInfo::SERVICE_TYPE_OPERATOR_20,   BarringInfo::SERVICE_TYPE_OPERATOR_21,
+            BarringInfo::SERVICE_TYPE_OPERATOR_22,   BarringInfo::SERVICE_TYPE_OPERATOR_23,
+            BarringInfo::SERVICE_TYPE_OPERATOR_24,   BarringInfo::SERVICE_TYPE_OPERATOR_25,
+            BarringInfo::SERVICE_TYPE_OPERATOR_26,   BarringInfo::SERVICE_TYPE_OPERATOR_27,
+            BarringInfo::SERVICE_TYPE_OPERATOR_28,   BarringInfo::SERVICE_TYPE_OPERATOR_29,
+            BarringInfo::SERVICE_TYPE_OPERATOR_30,   BarringInfo::SERVICE_TYPE_OPERATOR_31,
+    };
+
+    const std::set<int>* compareTo = nullptr;
+
+    switch (radioRsp_network->barringCellIdentity.getTag()) {
+        case CellIdentity::Tag::wcdma:
+            // fall through
+        case CellIdentity::Tag::tdscdma:
+            compareTo = &UTRA_SERVICES;
+            break;
+        case CellIdentity::Tag::lte:
+            compareTo = &EUTRA_SERVICES;
+            break;
+        case CellIdentity::Tag::nr:
+            compareTo = &NGRA_SERVICES;
+            break;
+        case CellIdentity::Tag::cdma:
+            // fall through
+        default:
+            FAIL();
+            break;
+    }
+
+    std::set<int> diff;
+
+    std::set_difference(reportedServices.begin(), reportedServices.end(), compareTo->begin(),
+                        compareTo->end(), std::inserter(diff, diff.begin()));
+}
+
+/*
+ * Test IRadioNetwork.getSignalStrength() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getSignalStrength) {
+    serial = GetRandomSerialNumber();
+
+    radio_network->getSignalStrength(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.getCellInfoList() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getCellInfoList) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->getCellInfoList(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);
+
+    ALOGI("getCellInfoList, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::NO_NETWORK_FOUND}));
+}
+
+/*
+ * Test IRadioNetwork.getVoiceRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getVoiceRegistrationState) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->getVoiceRegistrationState(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);
+
+    ALOGI("getVoiceRegistrationStateResponse, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+}
+
+/*
+ * Test IRadioNetwork.getDataRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getDataRegistrationState) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->getDataRegistrationState(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);
+
+    ALOGI("getDataRegistrationStateResponse, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NOT_PROVISIONED}));
+
+    // Check the mcc [0, 999] and mnc [0, 999].
+    std::string mcc;
+    std::string mnc;
+    bool checkMccMnc = true;
+    CellIdentity cellIdentity = radioRsp_network->dataRegResp.cellIdentity;
+    switch (cellIdentity.getTag()) {
+        case CellIdentity::noinit: {
+            checkMccMnc = false;
+            break;
+        }
+        case CellIdentity::gsm: {
+            CellIdentityGsm cig = cellIdentity.get<CellIdentity::gsm>();
+            mcc = cig.mcc;
+            mnc = cig.mnc;
+            break;
+        }
+        case CellIdentity::wcdma: {
+            CellIdentityWcdma ciw = cellIdentity.get<CellIdentity::wcdma>();
+            mcc = ciw.mcc;
+            mnc = ciw.mnc;
+            break;
+        }
+        case CellIdentity::tdscdma: {
+            CellIdentityTdscdma cit = cellIdentity.get<CellIdentity::tdscdma>();
+            mcc = cit.mcc;
+            mnc = cit.mnc;
+            break;
+        }
+        case CellIdentity::cdma: {
+            // CellIdentityCdma has no mcc/mnc
+            CellIdentityCdma cic = cellIdentity.get<CellIdentity::cdma>();
+            checkMccMnc = false;
+            break;
+        }
+        case CellIdentity::lte: {
+            CellIdentityLte cil = cellIdentity.get<CellIdentity::lte>();
+            mcc = cil.mcc;
+            mnc = cil.mnc;
+            break;
+        }
+        case CellIdentity::nr: {
+            CellIdentityNr cin = cellIdentity.get<CellIdentity::nr>();
+            mcc = cin.mcc;
+            mnc = cin.mnc;
+            break;
+        }
+    }
+
+    // 32 bit system might return invalid mcc and mnc string "\xff\xff..."
+    if (checkMccMnc && mcc.size() < 4 && mnc.size() < 4) {
+        int mcc_int = stoi(mcc);
+        int mnc_int = stoi(mnc);
+        EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
+        EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+    }
+
+    // Check for access technology specific info
+    AccessTechnologySpecificInfo info = radioRsp_network->dataRegResp.accessTechnologySpecificInfo;
+    RadioTechnology rat = radioRsp_network->dataRegResp.rat;
+    // TODO: add logic for cdmaInfo
+    if (rat == RadioTechnology::LTE || rat == RadioTechnology::LTE_CA) {
+        ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::eutranInfo);
+    } else if (rat == RadioTechnology::NR) {
+        ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::ngranNrVopsInfo);
+    }
+}
+
+/*
+ * Test IRadioNetwork.getAvailableBandModes() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAvailableBandModes) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->getAvailableBandModes(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);
+    ALOGI("getAvailableBandModes, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INTERNAL_ERR,
+                                  // If REQUEST_NOT_SUPPORTED is returned, then it should also be
+                                  // returned for setBandMode().
+                                  RadioError::REQUEST_NOT_SUPPORTED}));
+    bool hasUnspecifiedBandMode = false;
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        for (const RadioBandMode& mode : radioRsp_network->radioBandModes) {
+            // Automatic mode selection must be supported
+            if (mode == RadioBandMode::BAND_MODE_UNSPECIFIED) hasUnspecifiedBandMode = true;
+        }
+        ASSERT_TRUE(hasUnspecifiedBandMode);
+    }
+}
+
+/*
+ * Test IRadioNetwork.setIndicationFilter()
+ */
+TEST_P(RadioNetworkTest, setIndicationFilter) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_network->setIndicationFilter(serial, static_cast<int>(IndicationFilter::ALL));
+    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);
+
+    ALOGI("setIndicationFilter, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadioNetwork.setBarringPassword() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setBarringPassword) {
+    serial = GetRandomSerialNumber();
+    std::string facility = "";
+    std::string oldPassword = "";
+    std::string newPassword = "";
+
+    radio_network->setBarringPassword(serial, facility, oldPassword, newPassword);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::FDN_CHECK_FAILURE,
+                                      RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioNetwork.setSuppServiceNotifications() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSuppServiceNotifications) {
+    serial = GetRandomSerialNumber();
+    bool enable = false;
+
+    radio_network->setSuppServiceNotifications(serial, enable);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.getImsRegistrationState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getImsRegistrationState) {
+    serial = GetRandomSerialNumber();
+
+    radio_network->getImsRegistrationState(serial);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::MODEM_ERR, RadioError::INVALID_MODEM_STATE},
+                CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioNetwork.getOperator() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getOperator) {
+    LOG(DEBUG) << "getOperator";
+    serial = GetRandomSerialNumber();
+
+    radio_network->getOperator(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+    }
+    LOG(DEBUG) << "getOperator finished";
+}
+
+/*
+ * Test IRadioNetwork.getNetworkSelectionMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getNetworkSelectionMode) {
+    LOG(DEBUG) << "getNetworkSelectionMode";
+    serial = GetRandomSerialNumber();
+
+    radio_network->getNetworkSelectionMode(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+    }
+    LOG(DEBUG) << "getNetworkSelectionMode finished";
+}
+
+/*
+ * Test IRadioNetwork.setNetworkSelectionModeAutomatic() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) {
+    LOG(DEBUG) << "setNetworkSelectionModeAutomatic";
+    serial = GetRandomSerialNumber();
+
+    radio_network->setNetworkSelectionModeAutomatic(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
+                                      RadioError::OPERATION_NOT_ALLOWED},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setNetworkSelectionModeAutomatic finished";
+}
+
+/*
+ * Test IRadioNetwork.getAvailableNetworks() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAvailableNetworks) {
+    LOG(DEBUG) << "getAvailableNetworks";
+    serial = GetRandomSerialNumber();
+
+    radio_network->getAvailableNetworks(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    ASSERT_TRUE(radioRsp_network->rspInfo.type == RadioResponseType::SOLICITED ||
+                radioRsp_network->rspInfo.type == RadioResponseType::SOLICITED_ACK_EXP);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::CANCELLED, RadioError::DEVICE_IN_USE,
+                 RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getAvailableNetworks finished";
+}
+
+/*
+ * Test IRadioNetwork.setBandMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setBandMode) {
+    LOG(DEBUG) << "setBandMode";
+    serial = GetRandomSerialNumber();
+
+    radio_network->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setBandMode finished";
+}
+
+/*
+ * Test IRadioNetwork.setLocationUpdates() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setLocationUpdates) {
+    LOG(DEBUG) << "setLocationUpdates";
+    serial = GetRandomSerialNumber();
+
+    radio_network->setLocationUpdates(serial, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    }
+    LOG(DEBUG) << "setLocationUpdates finished";
+}
+
+/*
+ * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
+    LOG(DEBUG) << "setCdmaRoamingPreference";
+    serial = GetRandomSerialNumber();
+
+    radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "setCdmaRoamingPreference finished";
+}
+
+/*
+ * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
+    LOG(DEBUG) << "getCdmaRoamingPreference";
+    serial = GetRandomSerialNumber();
+
+    radio_network->getCdmaRoamingPreference(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
+                                 CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getCdmaRoamingPreference finished";
+}
+
+/*
+ * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
+ */
+TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
+    LOG(DEBUG) << "getVoiceRadioTechnology";
+    serial = GetRandomSerialNumber();
+
+    radio_network->getVoiceRadioTechnology(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
+    }
+    LOG(DEBUG) << "getVoiceRadioTechnology finished";
+}
+
+/*
+ * Test IRadioNetwork.setCellInfoListRate() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setCellInfoListRate) {
+    LOG(DEBUG) << "setCellInfoListRate";
+    serial = GetRandomSerialNumber();
+
+    radio_network->setCellInfoListRate(serial, 10);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "setCellInfoListRate finished";
+}
+
+/*
+ * Test IRadioNetwork.supplyNetworkDepersonalization() for the response returned.
+ */
+TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) {
+    LOG(DEBUG) << "supplyNetworkDepersonalization";
+    serial = GetRandomSerialNumber();
+
+    radio_network->supplyNetworkDepersonalization(serial, std::string("test"));
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INTERNAL_ERR,
+                 RadioError::INVALID_SIM_STATE, RadioError::MODEM_ERR, RadioError::NO_MEMORY,
+                 RadioError::PASSWORD_INCORRECT, RadioError::SIM_ABSENT, RadioError::SYSTEM_ERR}));
+    }
+    LOG(DEBUG) << "supplyNetworkDepersonalization finished";
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index c26d7c3..29ba2f2 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -41,8 +41,10 @@
     bool isNrDualConnectivityEnabled;
     int networkTypeBitmapResponse;
     RegStateResult voiceRegResp;
+    RegStateResult dataRegResp;
     CellIdentity barringCellIdentity;
-    std::vector<BarringInfo> barringInfos;
+    std::vector<BarringInfo> barringInfoList;
+    UsageSetting usageSetting;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
@@ -211,4 +213,12 @@
     std::shared_ptr<RadioNetworkResponse> radioRsp_network;
     /* radio network indication handle */
     std::shared_ptr<RadioNetworkIndication> radioInd_network;
+
+    void invokeAndExpectResponse(std::function<ndk::ScopedAStatus(int32_t serial)> request,
+                                 std::vector<RadioError> errors_to_check);
+
+    // Helper function to reduce copy+paste
+    void testSetUsageSetting_InvalidValues(std::vector<RadioError> errors);
+
+    void stopNetworkScan();
 };
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
index a783f43..391c9cb 100644
--- a/radio/aidl/vts/radio_sim_response.cpp
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -23,44 +23,62 @@
 }
 
 ndk::ScopedAStatus RadioSimResponse::areUiccApplicationsEnabledResponse(
-        const RadioResponseInfo& /*info*/, bool /*enabled*/) {
+        const RadioResponseInfo& info, bool enabled) {
+    rspInfo = info;
+    areUiccApplicationsEnabled = enabled;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& info,
                                                                  int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& info,
                                                                 int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::getAllowedCarriersResponse(
-        const RadioResponseInfo& /*info*/, const CarrierRestrictions& /*carriers*/,
-        SimLockMultiSimPolicy /*multiSimPolicy*/) {
+        const RadioResponseInfo& info, const CarrierRestrictions& carriers,
+        SimLockMultiSimPolicy multiSimPolicy) {
+    rspInfo = info;
+    carrierRestrictionsResp = carriers;
+    multiSimPolicyResp = multiSimPolicy;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionResponse(
-        const RadioResponseInfo& /*info*/, const std::string& /*mdn*/, const std::string& /*hSid*/,
+        const RadioResponseInfo& info, const std::string& /*mdn*/, const std::string& /*hSid*/,
         const std::string& /*hNid*/, const std::string& /*min*/, const std::string& /*prl*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionSourceResponse(
-        const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+        const RadioResponseInfo& info, CdmaSubscriptionSource /*source*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*response*/) {
+ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                                   int32_t /*response*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -72,8 +90,11 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& /*info*/,
-                                                           const std::string& /*imsi*/) {
+ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& info,
+                                                           const std::string& imsi_str) {
+    rspInfo = info;
+    imsi = imsi_str;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -91,58 +112,79 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& info,
                                                          const IccIoResult& /*iccIo*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::iccOpenLogicalChannelResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+        const RadioResponseInfo& info, int32_t /*channelId*/,
         const std::vector<uint8_t>& /*selectResponse*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::iccTransmitApduBasicChannelResponse(
-        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+        const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::iccTransmitApduLogicalChannelResponse(
-        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+        const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::reportStkServiceIsRunningResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::requestIccSimAuthenticationResponse(
-        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+        const RadioResponseInfo& info, const IccIoResult& /*result*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& info,
                                                           const std::string& /*commandResponse*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(
-        const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+                                                                    const IccIoResult& /*iccIo*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::sendTerminalResponseToSimResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -154,12 +196,16 @@
 }
 
 ndk::ScopedAStatus RadioSimResponse::setCdmaSubscriptionSourceResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*retry*/) {
+ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                                   int32_t /*retry*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -169,34 +215,44 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
                                                                  int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& info,
                                                                 int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
                                                                  int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& info,
                                                                 int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioSimResponse::supplySimDepersonalizationResponse(
-        const RadioResponseInfo& /*info*/, PersoSubstate /*persoType*/,
-        int32_t /*remainingRetries*/) {
+        const RadioResponseInfo& info, PersoSubstate /*persoType*/, int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    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
index 5db77f6..64474c9 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <aidl/android/hardware/radio/RadioConst.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
@@ -260,3 +261,764 @@
         }
     }
 }
+
+/*
+ * Test IRadioSim.enableUiccApplications() for the response returned.
+ * For SIM ABSENT case.
+ */
+TEST_P(RadioSimTest, togglingUiccApplicationsSimAbsent) {
+    // This test case only test SIM ABSENT case.
+    if (cardStatus.cardState != CardStatus::STATE_ABSENT) return;
+
+    // Disable Uicc applications.
+    serial = GetRandomSerialNumber();
+    radio_sim->enableUiccApplications(serial, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+    EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+
+    // Query Uicc application enablement.
+    serial = GetRandomSerialNumber();
+    radio_sim->areUiccApplicationsEnabled(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+    EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+}
+
+/*
+ * Test IRadioSim.enableUiccApplications() for the response returned.
+ * For SIM PRESENT case.
+ */
+TEST_P(RadioSimTest, togglingUiccApplicationsSimPresent) {
+    // This test case only test SIM ABSENT case.
+    if (cardStatus.cardState != CardStatus::STATE_PRESENT) return;
+    if (cardStatus.applications.size() == 0) return;
+
+    // Disable Uicc applications.
+    serial = GetRandomSerialNumber();
+    radio_sim->enableUiccApplications(serial, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is present, there shouldn't be error.
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+    // Query Uicc application enablement.
+    serial = GetRandomSerialNumber();
+    radio_sim->areUiccApplicationsEnabled(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is present, there shouldn't be error.
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+    ASSERT_FALSE(radioRsp_sim->areUiccApplicationsEnabled);
+
+    // Enable Uicc applications.
+    serial = GetRandomSerialNumber();
+    radio_sim->enableUiccApplications(serial, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is present, there shouldn't be error.
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+
+    // Query Uicc application enablement.
+    serial = GetRandomSerialNumber();
+    radio_sim->areUiccApplicationsEnabled(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    // As SIM is present, there shouldn't be error.
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+    ASSERT_TRUE(radioRsp_sim->areUiccApplicationsEnabled);
+}
+
+/*
+ * Test IRadioSim.areUiccApplicationsEnabled() for the response returned.
+ */
+TEST_P(RadioSimTest, areUiccApplicationsEnabled) {
+    // Disable Uicc applications.
+    serial = GetRandomSerialNumber();
+    radio_sim->areUiccApplicationsEnabled(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 SIM is absent, RadioError::SIM_ABSENT should be thrown. Otherwise there shouldn't be any
+    // error.
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_sim->rspInfo.error);
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadioSim.getAllowedCarriers() for the response returned.
+ */
+TEST_P(RadioSimTest, getAllowedCarriers) {
+    serial = GetRandomSerialNumber();
+
+    radio_sim->getAllowedCarriers(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}));
+}
+
+/**
+ * Test IRadioSim.setAllowedCarriers() for the response returned.
+ */
+TEST_P(RadioSimTest, setAllowedCarriers) {
+    // TODO (b/210712359): remove once shim supports 1.4 or alternative is found
+    GTEST_SKIP();
+    serial = GetRandomSerialNumber();
+    CarrierRestrictions carrierRestrictions;
+    memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
+    carrierRestrictions.allowedCarriers.resize(1);
+    carrierRestrictions.excludedCarriers.resize(0);
+    carrierRestrictions.allowedCarriers[0].mcc = std::string("123");
+    carrierRestrictions.allowedCarriers[0].mnc = std::string("456");
+    carrierRestrictions.allowedCarriers[0].matchType = Carrier::MATCH_TYPE_ALL;
+    carrierRestrictions.allowedCarriers[0].matchData = std::string();
+    carrierRestrictions.allowedCarriersPrioritized = true;
+    SimLockMultiSimPolicy multisimPolicy = SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+
+    radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
+    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}));
+
+    if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+        /* Verify the update of the SIM status. This might need some time */
+        if (cardStatus.cardState != CardStatus::STATE_ABSENT) {
+            updateSimCardStatus();
+            auto startTime = std::chrono::system_clock::now();
+            while (cardStatus.cardState != CardStatus::STATE_RESTRICTED &&
+                   std::chrono::duration_cast<std::chrono::seconds>(
+                           std::chrono::system_clock::now() - startTime)
+                                   .count() < 30) {
+                /* Set 2 seconds as interval to check card status */
+                sleep(2);
+                updateSimCardStatus();
+            }
+            EXPECT_EQ(CardStatus::STATE_RESTRICTED, cardStatus.cardState);
+        }
+
+        /* Verify that configuration was set correctly, retrieving it from the modem */
+        serial = GetRandomSerialNumber();
+
+        radio_sim->getAllowedCarriers(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);
+
+        EXPECT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
+        EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarriers.size());
+        ASSERT_TRUE(std::string("123") ==
+                    radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mcc);
+        ASSERT_TRUE(std::string("456") ==
+                    radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mnc);
+        EXPECT_EQ(Carrier::MATCH_TYPE_ALL,
+                  radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].matchType);
+        ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
+        EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
+
+        sleep(10);
+
+        /**
+         * Another test case of the API to cover to allow carrier.
+         * If the API is supported, this is also used to reset to no carrier restriction
+         * status for cardStatus.
+         */
+        memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
+        carrierRestrictions.allowedCarriers.resize(0);
+        carrierRestrictions.excludedCarriers.resize(0);
+        carrierRestrictions.allowedCarriersPrioritized = false;
+
+        serial = GetRandomSerialNumber();
+        radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
+        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);
+
+        if (cardStatus.cardState != CardStatus::STATE_ABSENT) {
+            /* Resetting back to no carrier restriction needs some time */
+            updateSimCardStatus();
+            auto startTime = std::chrono::system_clock::now();
+            while (cardStatus.cardState == CardStatus::STATE_RESTRICTED &&
+                   std::chrono::duration_cast<std::chrono::seconds>(
+                           std::chrono::system_clock::now() - startTime)
+                                   .count() < 10) {
+                /* Set 2 seconds as interval to check card status */
+                sleep(2);
+                updateSimCardStatus();
+            }
+            EXPECT_NE(CardStatus::STATE_RESTRICTED, cardStatus.cardState);
+            sleep(10);
+        }
+    }
+}
+
+/*
+ * Test IRadioSim.getIccCardStatus() for the response returned.
+ */
+TEST_P(RadioSimTest, getIccCardStatus) {
+    LOG(DEBUG) << "getIccCardStatus";
+    EXPECT_LE(cardStatus.applications.size(), RadioConst::CARD_MAX_APPS);
+    EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+    EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+    EXPECT_LT(cardStatus.imsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
+    LOG(DEBUG) << "getIccCardStatus finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPinForApp() for the response returned
+ */
+TEST_P(RadioSimTest, supplyIccPinForApp) {
+    LOG(DEBUG) << "supplyIccPinForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->supplyIccPinForApp(serial, std::string("test1"),
+                                          cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_sim->rspInfo.error,
+                    {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
+        }
+    }
+    LOG(DEBUG) << "supplyIccPinForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPukForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPukForApp) {
+    LOG(DEBUG) << "supplyIccPukForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->supplyIccPukForApp(serial, std::string("test1"), std::string("test2"),
+                                          cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_sim->rspInfo.error,
+                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+        }
+    }
+    LOG(DEBUG) << "supplyIccPukForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPin2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPin2ForApp) {
+    LOG(DEBUG) << "supplyIccPin2ForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->supplyIccPin2ForApp(serial, std::string("test1"),
+                                           cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(
+                    CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::PASSWORD_INCORRECT,
+                                      RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
+        }
+    }
+    LOG(DEBUG) << "supplyIccPin2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.supplyIccPuk2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, supplyIccPuk2ForApp) {
+    LOG(DEBUG) << "supplyIccPuk2ForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->supplyIccPuk2ForApp(serial, std::string("test1"), std::string("test2"),
+                                           cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_sim->rspInfo.error,
+                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+        }
+    }
+    LOG(DEBUG) << "supplyIccPuk2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.changeIccPinForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, changeIccPinForApp) {
+    LOG(DEBUG) << "changeIccPinForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->changeIccPinForApp(serial, std::string("test1"), std::string("test2"),
+                                          cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_sim->rspInfo.error,
+                    {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
+        }
+    }
+    LOG(DEBUG) << "changeIccPinForApp finished";
+}
+
+/*
+ * Test IRadioSim.changeIccPin2ForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, changeIccPin2ForApp) {
+    LOG(DEBUG) << "changeIccPin2ForApp";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
+    // 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->changeIccPin2ForApp(serial, std::string("test1"), std::string("test2"),
+                                           cardStatus.applications[i].aidPtr);
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            ASSERT_TRUE(
+                    CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::PASSWORD_INCORRECT,
+                                      RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
+        }
+    }
+    LOG(DEBUG) << "changeIccPin2ForApp finished";
+}
+
+/*
+ * Test IRadioSim.getImsiForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, getImsiForApp) {
+    LOG(DEBUG) << "getImsiForApp";
+    serial = GetRandomSerialNumber();
+
+    // Check success returned while getting imsi for 3GPP and 3GPP2 apps only
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        if (cardStatus.applications[i].appType == AppStatus::APP_TYPE_SIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_USIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_RUIM ||
+            cardStatus.applications[i].appType == AppStatus::APP_TYPE_CSIM) {
+            radio_sim->getImsiForApp(serial, cardStatus.applications[i].aidPtr);
+            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},
+                                         CHECK_GENERAL_ERROR));
+
+            // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more than 15
+            if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+                EXPECT_NE(radioRsp_sim->imsi, std::string());
+                EXPECT_GE((int)(radioRsp_sim->imsi).size(), 6);
+                EXPECT_LE((int)(radioRsp_sim->imsi).size(), 15);
+            }
+        }
+    }
+    LOG(DEBUG) << "getImsiForApp finished";
+}
+
+/*
+ * Test IRadioSim.iccIoForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, iccIoForApp) {
+    LOG(DEBUG) << "iccIoForApp";
+    serial = GetRandomSerialNumber();
+
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        IccIo iccIo;
+        iccIo.command = 0xc0;
+        iccIo.fileId = 0x6f11;
+        iccIo.path = std::string("3F007FFF");
+        iccIo.p1 = 0;
+        iccIo.p2 = 0;
+        iccIo.p3 = 0;
+        iccIo.data = std::string();
+        iccIo.pin2 = std::string();
+        iccIo.aid = cardStatus.applications[i].aidPtr;
+
+        radio_sim->iccIoForApp(serial, iccIo);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    }
+    LOG(DEBUG) << "iccIoForApp finished";
+}
+
+/*
+ * Test IRadioSim.iccTransmitApduBasicChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccTransmitApduBasicChannel) {
+    LOG(DEBUG) << "iccTransmitApduBasicChannel";
+    serial = GetRandomSerialNumber();
+    SimApdu msg;
+    memset(&msg, 0, sizeof(msg));
+    msg.data = std::string();
+
+    radio_sim->iccTransmitApduBasicChannel(serial, msg);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    LOG(DEBUG) << "iccTransmitApduBasicChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccOpenLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccOpenLogicalChannel) {
+    LOG(DEBUG) << "iccOpenLogicalChannel";
+    serial = GetRandomSerialNumber();
+    int p2 = 0x04;
+    // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        radio_sim->iccOpenLogicalChannel(serial, cardStatus.applications[i].aidPtr, p2);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    }
+    LOG(DEBUG) << "iccOpenLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccCloseLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccCloseLogicalChannel) {
+    LOG(DEBUG) << "iccCloseLogicalChannel";
+    serial = GetRandomSerialNumber();
+    // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
+    radio_sim->iccCloseLogicalChannel(serial, 0);
+    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::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error);
+    LOG(DEBUG) << "iccCloseLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned.
+ */
+TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) {
+    LOG(DEBUG) << "iccTransmitApduLogicalChannel";
+    serial = GetRandomSerialNumber();
+    SimApdu msg;
+    memset(&msg, 0, sizeof(msg));
+    msg.data = std::string();
+
+    radio_sim->iccTransmitApduLogicalChannel(serial, msg);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    LOG(DEBUG) << "iccTransmitApduLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.requestIccSimAuthentication() for the response returned.
+ */
+TEST_P(RadioSimTest, requestIccSimAuthentication) {
+    LOG(DEBUG) << "requestIccSimAuthentication";
+    serial = GetRandomSerialNumber();
+
+    // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
+    // or REQUEST_NOT_SUPPORTED returned as error.
+    for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
+        radio_sim->requestIccSimAuthentication(serial, 0, std::string("test"),
+                                               cardStatus.applications[i].aidPtr);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_sim->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "requestIccSimAuthentication finished";
+}
+
+/*
+ * Test IRadioSim.getFacilityLockForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, getFacilityLockForApp) {
+    serial = GetRandomSerialNumber();
+    std::string facility = "";
+    std::string password = "";
+    int32_t serviceClass = 1;
+    std::string appId = "";
+
+    radio_sim->getFacilityLockForApp(serial, facility, password, serviceClass, appId);
+
+    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_ARGUMENTS, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioSim.setFacilityLockForApp() for the response returned.
+ */
+TEST_P(RadioSimTest, setFacilityLockForApp) {
+    serial = GetRandomSerialNumber();
+    std::string facility = "";
+    bool lockState = false;
+    std::string password = "";
+    int32_t serviceClass = 1;
+    std::string appId = "";
+
+    radio_sim->setFacilityLockForApp(serial, facility, lockState, password, serviceClass, appId);
+
+    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_ARGUMENTS, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioSim.getCdmaSubscription() for the response returned.
+ */
+TEST_P(RadioSimTest, getCdmaSubscription) {
+    LOG(DEBUG) << "getCdmaSubscription";
+    serial = GetRandomSerialNumber();
+
+    radio_sim->getCdmaSubscription(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::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+    }
+    LOG(DEBUG) << "getCdmaSubscription finished";
+}
+
+/*
+ * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
+ */
+TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
+    LOG(DEBUG) << "getCdmaSubscriptionSource";
+    serial = GetRandomSerialNumber();
+
+    radio_sim->getCdmaSubscriptionSource(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::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+    }
+    LOG(DEBUG) << "getCdmaSubscriptionSource finished";
+}
+
+/*
+ * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
+ */
+TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
+    LOG(DEBUG) << "setCdmaSubscriptionSource";
+    serial = GetRandomSerialNumber();
+
+    radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
+    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::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setCdmaSubscriptionSource finished";
+}
+
+/*
+ * Test IRadioSim.setUiccSubscription() for the response returned.
+ */
+TEST_P(RadioSimTest, setUiccSubscription) {
+    LOG(DEBUG) << "setUiccSubscription";
+    serial = GetRandomSerialNumber();
+    SelectUiccSub item;
+    memset(&item, 0, sizeof(item));
+
+    radio_sim->setUiccSubscription(serial, item);
+    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::INVALID_ARGUMENTS,
+                                  RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setUiccSubscription finished";
+}
+
+/*
+ * Test IRadioSim.sendEnvelope() for the response returned.
+ */
+TEST_P(RadioSimTest, sendEnvelope) {
+    LOG(DEBUG) << "sendEnvelope";
+    serial = GetRandomSerialNumber();
+
+    // Test with sending empty string
+    std::string content = "";
+
+    radio_sim->sendEnvelope(serial, content);
+
+    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::INVALID_ARGUMENTS,
+                                      RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendEnvelope finished";
+}
+
+/*
+ * Test IRadioSim.sendTerminalResponseToSim() for the response returned.
+ */
+TEST_P(RadioSimTest, sendTerminalResponseToSim) {
+    LOG(DEBUG) << "sendTerminalResponseToSim";
+    serial = GetRandomSerialNumber();
+
+    // Test with sending empty string
+    std::string commandResponse = "";
+
+    radio_sim->sendTerminalResponseToSim(serial, commandResponse);
+
+    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::INVALID_ARGUMENTS, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendTerminalResponseToSim finished";
+}
+
+/*
+ * Test IRadioSim.reportStkServiceIsRunning() for the response returned.
+ */
+TEST_P(RadioSimTest, reportStkServiceIsRunning) {
+    LOG(DEBUG) << "reportStkServiceIsRunning";
+    serial = GetRandomSerialNumber();
+
+    radio_sim->reportStkServiceIsRunning(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::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "reportStkServiceIsRunning finished";
+}
+
+/*
+ * Test IRadioSim.sendEnvelopeWithStatus() for the response returned with empty
+ * string.
+ */
+TEST_P(RadioSimTest, sendEnvelopeWithStatus) {
+    LOG(DEBUG) << "sendEnvelopeWithStatus";
+    serial = GetRandomSerialNumber();
+
+    // Test with sending empty string
+    std::string contents = "";
+
+    radio_sim->sendEnvelopeWithStatus(serial, contents);
+
+    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_ARGUMENTS, RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendEnvelopeWithStatus finished";
+}
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index b5e365d..83f1cbc 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -42,6 +42,7 @@
     bool areUiccApplicationsEnabled;
     PhonebookCapacity capacity;
     int32_t updatedRecordIndex;
+    std::string imsi;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
diff --git a/radio/aidl/vts/radio_voice_indication.cpp b/radio/aidl/vts/radio_voice_indication.cpp
index d814c18..3fee326 100644
--- a/radio/aidl/vts/radio_voice_indication.cpp
+++ b/radio/aidl/vts/radio_voice_indication.cpp
@@ -65,6 +65,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus RadioVoiceIndication::onUssd(RadioIndicationType /*type*/,
+                                                UssdModeType /*modeType*/,
+                                                const std::string& /*msg*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus RadioVoiceIndication::resendIncallMute(RadioIndicationType /*type*/) {
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_voice_response.cpp b/radio/aidl/vts/radio_voice_response.cpp
index a491613..dd7b1bf 100644
--- a/radio/aidl/vts/radio_voice_response.cpp
+++ b/radio/aidl/vts/radio_voice_response.cpp
@@ -18,7 +18,9 @@
 
 RadioVoiceResponse::RadioVoiceResponse(RadioServiceTest& parent) : parent_voice(parent) {}
 
-ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -26,11 +28,21 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::cancelPendingUssdResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -41,34 +53,44 @@
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::exitEmergencyCallbackModeResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::getCallForwardStatusResponse(
-        const RadioResponseInfo& /*info*/,
-        const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+        const RadioResponseInfo& info, const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& info,
                                                               bool /*enable*/,
                                                               int32_t /*serviceClass*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& info,
                                                        ClipStatus /*status*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& /*info*/,
-                                                       int32_t /*n*/, int32_t /*m*/) {
+ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& info, int32_t /*n*/,
+                                                       int32_t /*m*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -81,27 +103,37 @@
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::getLastCallFailCauseResponse(
-        const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+        const RadioResponseInfo& info, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& info,
                                                        bool /*enable*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::getPreferredVoicePrivacyResponse(
-        const RadioResponseInfo& /*info*/, bool /*enable*/) {
+        const RadioResponseInfo& info, bool /*enable*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& info,
                                                           TtyMode /*mode*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::handleStkCallSetupRequestFromSimResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -112,80 +144,120 @@
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::hangupForegroundResumeBackgroundResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::hangupWaitingOrBackgroundResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& /*info*/,
+ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& info,
                                                              bool /*enabled*/) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(
-        const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::sendUssdResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::setPreferredVoicePrivacyResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus RadioVoiceResponse::switchWaitingOrHoldingAndActiveResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 717f3f0..eec28b1 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -265,3 +265,681 @@
     EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
 }
+
+/*
+ * Test IRadioVoice.getClir() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getClir) {
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getClir(serial);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioVoice.setClir() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setClir) {
+    serial = GetRandomSerialNumber();
+    int32_t status = 1;
+
+    radio_voice->setClir(serial, status);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadioVoice.getClip() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getClip) {
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getClip(serial);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioVoice.getTtyMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getTtyMode) {
+    LOG(DEBUG) << "getTtyMode";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getTtyMode(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+    }
+    LOG(DEBUG) << "getTtyMode finished";
+}
+
+/*
+ * Test IRadioVoice.setTtyMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setTtyMode) {
+    LOG(DEBUG) << "setTtyMode";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->setTtyMode(serial, TtyMode::OFF);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+    }
+    LOG(DEBUG) << "setTtyMode finished";
+}
+
+/*
+ * Test IRadioVoice.setPreferredVoicePrivacy() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) {
+    LOG(DEBUG) << "setPreferredVoicePrivacy";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->setPreferredVoicePrivacy(serial, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "setPreferredVoicePrivacy finished";
+}
+
+/*
+ * Test IRadioVoice.getPreferredVoicePrivacy() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) {
+    LOG(DEBUG) << "getPreferredVoicePrivacy";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getPreferredVoicePrivacy(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+    LOG(DEBUG) << "getPreferredVoicePrivacy finished";
+}
+
+/*
+ * Test IRadioVoice.exitEmergencyCallbackMode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) {
+    LOG(DEBUG) << "exitEmergencyCallbackMode";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->exitEmergencyCallbackMode(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
+    }
+    LOG(DEBUG) << "exitEmergencyCallbackMode finished";
+}
+
+/*
+ * Test IRadioVoice.handleStkCallSetupRequestFromSim() for the response returned.
+ */
+TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) {
+    LOG(DEBUG) << "handleStkCallSetupRequestFromSim";
+    serial = GetRandomSerialNumber();
+    bool accept = false;
+
+    radio_voice->handleStkCallSetupRequestFromSim(serial, accept);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                      RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "handleStkCallSetupRequestFromSim finished";
+}
+
+/*
+ * Test IRadioVoice.dial() for the response returned.
+ */
+TEST_P(RadioVoiceTest, dial) {
+    LOG(DEBUG) << "dial";
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    memset(&dialInfo, 0, sizeof(dialInfo));
+    dialInfo.address = std::string("123456789");
+
+    radio_voice->dial(serial, dialInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::CANCELLED, RadioError::DEVICE_IN_USE, RadioError::FDN_CHECK_FAILURE,
+                 RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+                 RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
+                 RadioError::NO_NETWORK_FOUND, RadioError::NO_SUBSCRIPTION,
+                 RadioError::OPERATION_NOT_ALLOWED},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "dial finished";
+}
+
+/*
+ * Test IRadioVoice.hangup() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangup) {
+    LOG(DEBUG) << "hangup";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->hangup(serial, 1);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "hangup finished";
+}
+
+/*
+ * Test IRadioVoice.hangupWaitingOrBackground() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangupWaitingOrBackground) {
+    LOG(DEBUG) << "hangupWaitingOrBackground";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->hangupWaitingOrBackground(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "hangupWaitingOrBackground finished";
+}
+
+/*
+ * Test IRadioVoice.hangupForegroundResumeBackground() for the response returned.
+ */
+TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) {
+    LOG(DEBUG) << "hangupForegroundResumeBackground";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->hangupForegroundResumeBackground(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "hangupForegroundResumeBackground finished";
+}
+
+/*
+ * Test IRadioVoice.switchWaitingOrHoldingAndActive() for the response returned.
+ */
+TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) {
+    LOG(DEBUG) << "switchWaitingOrHoldingAndActive";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->switchWaitingOrHoldingAndActive(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "switchWaitingOrHoldingAndActive finished";
+}
+
+/*
+ * Test IRadioVoice.conference() for the response returned.
+ */
+TEST_P(RadioVoiceTest, conference) {
+    LOG(DEBUG) << "conference";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->conference(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "conference finished";
+}
+
+/*
+ * Test IRadioVoice.rejectCall() for the response returned.
+ */
+TEST_P(RadioVoiceTest, rejectCall) {
+    LOG(DEBUG) << "rejectCall";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->rejectCall(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "rejectCall finished";
+}
+
+/*
+ * Test IRadioVoice.getLastCallFailCause() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getLastCallFailCause) {
+    LOG(DEBUG) << "getLastCallFailCause";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getLastCallFailCause(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getLastCallFailCause finished";
+}
+
+/*
+ * Test IRadioVoice.getCallForwardStatus() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCallForwardStatus) {
+    LOG(DEBUG) << "getCallForwardStatus";
+    serial = GetRandomSerialNumber();
+    CallForwardInfo callInfo;
+    memset(&callInfo, 0, sizeof(callInfo));
+    callInfo.number = std::string();
+
+    radio_voice->getCallForwardStatus(serial, callInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getCallForwardStatus finished";
+}
+
+/*
+ * Test IRadioVoice.setCallForward() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setCallForward) {
+    LOG(DEBUG) << "setCallForward";
+    serial = GetRandomSerialNumber();
+    CallForwardInfo callInfo;
+    memset(&callInfo, 0, sizeof(callInfo));
+    callInfo.number = std::string();
+
+    radio_voice->setCallForward(serial, callInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setCallForward finished";
+}
+
+/*
+ * Test IRadioVoice.getCallWaiting() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCallWaiting) {
+    LOG(DEBUG) << "getCallWaiting";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getCallWaiting(serial, 1);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "getCallWaiting finished";
+}
+
+/*
+ * Test IRadioVoice.setCallWaiting() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setCallWaiting) {
+    LOG(DEBUG) << "setCallWaiting";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->setCallWaiting(serial, true, 1);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setCallWaiting finished";
+}
+
+/*
+ * Test IRadioVoice.acceptCall() for the response returned.
+ */
+TEST_P(RadioVoiceTest, acceptCall) {
+    LOG(DEBUG) << "acceptCall";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->acceptCall(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "acceptCall finished";
+}
+
+/*
+ * Test IRadioVoice.separateConnection() for the response returned.
+ */
+TEST_P(RadioVoiceTest, separateConnection) {
+    LOG(DEBUG) << "separateConnection";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->separateConnection(serial, 1);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "separateConnection finished";
+}
+
+/*
+ * Test IRadioVoice.explicitCallTransfer() for the response returned.
+ */
+TEST_P(RadioVoiceTest, explicitCallTransfer) {
+    LOG(DEBUG) << "explicitCallTransfer";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->explicitCallTransfer(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "explicitCallTransfer finished";
+}
+
+/*
+ * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
+    LOG(DEBUG) << "sendCdmaFeatureCode";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->sendCdmaFeatureCode(serial, std::string());
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                      RadioError::INVALID_CALL_ID, RadioError::INVALID_MODEM_STATE,
+                                      RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendCdmaFeatureCode finished";
+}
+
+/*
+ * Test IRadioVoice.sendDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendDtmf) {
+    LOG(DEBUG) << "sendDtmf";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->sendDtmf(serial, "1");
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+                 RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.startDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, startDtmf) {
+    LOG(DEBUG) << "startDtmf";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->startDtmf(serial, "1");
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_CALL_ID,
+                 RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "startDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.stopDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, stopDtmf) {
+    LOG(DEBUG) << "stopDtmf";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->stopDtmf(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_CALL_ID,
+                                      RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "stopDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.setMute() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setMute) {
+    LOG(DEBUG) << "setMute";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->setMute(serial, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "setMute finished";
+}
+
+/*
+ * Test IRadioVoice.getMute() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getMute) {
+    LOG(DEBUG) << "getMute";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->getMute(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+    }
+    LOG(DEBUG) << "getMute finished";
+}
+
+/*
+ * Test IRadioVoice.sendBurstDtmf() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendBurstDtmf) {
+    LOG(DEBUG) << "sendBurstDtmf";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->sendBurstDtmf(serial, "1", 0, 0);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+                                     {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE,
+                                      RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
+                                     CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendBurstDtmf finished";
+}
+
+/*
+ * Test IRadioVoice.sendUssd() for the response returned.
+ */
+TEST_P(RadioVoiceTest, sendUssd) {
+    LOG(DEBUG) << "sendUssd";
+    serial = GetRandomSerialNumber();
+    radio_voice->sendUssd(serial, std::string("test"));
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendUssd finished";
+}
+
+/*
+ * Test IRadioVoice.cancelPendingUssd() for the response returned.
+ */
+TEST_P(RadioVoiceTest, cancelPendingUssd) {
+    LOG(DEBUG) << "cancelPendingUssd";
+    serial = GetRandomSerialNumber();
+
+    radio_voice->cancelPendingUssd(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_voice->rspInfo.error,
+                {RadioError::NONE, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "cancelPendingUssd finished";
+}
diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h
index d61bf1e..0c3df7f 100644
--- a/radio/aidl/vts/radio_voice_utils.h
+++ b/radio/aidl/vts/radio_voice_utils.h
@@ -43,6 +43,8 @@
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
+    virtual ndk::ScopedAStatus cancelPendingUssdResponse(const RadioResponseInfo& info) override;
+
     virtual ndk::ScopedAStatus conferenceResponse(const RadioResponseInfo& info) override;
 
     virtual ndk::ScopedAStatus dialResponse(const RadioResponseInfo& info) override;
@@ -103,6 +105,8 @@
 
     virtual ndk::ScopedAStatus sendDtmfResponse(const RadioResponseInfo& info) override;
 
+    virtual ndk::ScopedAStatus sendUssdResponse(const RadioResponseInfo& info) override;
+
     virtual ndk::ScopedAStatus separateConnectionResponse(const RadioResponseInfo& info) override;
 
     virtual ndk::ScopedAStatus setCallForwardResponse(const RadioResponseInfo& info) override;
@@ -164,6 +168,9 @@
     virtual ndk::ScopedAStatus onSupplementaryServiceIndication(
             RadioIndicationType type, const StkCcUnsolSsResult& ss) override;
 
+    virtual ndk::ScopedAStatus onUssd(RadioIndicationType type, UssdModeType modeType,
+                                      const std::string& msg) override;
+
     virtual ndk::ScopedAStatus resendIncallMute(RadioIndicationType type) override;
 
     virtual ndk::ScopedAStatus srvccStateNotify(RadioIndicationType type,
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index fb736e3..c9ee1b3 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -55,6 +55,13 @@
     ],
 }
 
+cc_defaults {
+    name: "keymint_use_latest_hal_aidl_cpp_static",
+    static_libs: [
+        "android.hardware.security.keymint-V2-cpp",
+    ],
+}
+
 // A rust_defaults that includes the latest KeyMint AIDL library.
 // Modules that depend on KeyMint directly can include this cc_defaults to avoid
 // managing dependency versions explicitly.
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index b0761bf..abb2a7b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -27,29 +27,29 @@
 @VintfStability
 parcelable DeviceInfo {
     /**
-     * DeviceInfo is a CBOR Map structure described by the following CDDL.
+     * DeviceInfo is a CBOR Map structure described by the following CDDL. DeviceInfo must be
+     * canonicalized according to the specification in RFC 7049. The ordering presented here is
+     * non-canonical to group similar entries semantically.
      *
      *     DeviceInfo = {
-     *         ? "brand" : tstr,
-     *         ? "manufacturer" : tstr,
-     *         ? "product" : tstr,
-     *         ? "model" : tstr,
-     *         ? "board" : tstr,
-     *         ? "vb_state" : "green" / "yellow" / "orange",    // Taken from the AVB values
-     *         ? "bootloader_state" : "locked" / "unlocked",    // Taken from the AVB values
-     *         ? "vbmeta_digest": bstr,                         // Taken from the AVB values
-     *         ? "os_version" : tstr,                    // Same as android.os.Build.VERSION.release
-     *         ? "system_patch_level" : uint,                   // YYYYMMDD
-     *         ? "boot_patch_level" : uint,                     // YYYYMMDD
-     *         ? "vendor_patch_level" : uint,                   // YYYYMMDD
-     *         "version" : 1,                      // The CDDL schema version.
-     *         "security_level" : "tee" / "strongbox"
-     *         "att_id_state": "locked" / "open",  // Attestation IDs State. If "locked", this
-     *                                             // indicates a device's attestable IDs are
-     *                                             // factory-locked and immutable. If "open",
-     *                                             // this indicates the device is still in a
-     *                                             // provisionable state and the attestable IDs
-     *                                             // are not yet frozen.
+     *         "brand" : tstr,
+     *         "manufacturer" : tstr,
+     *         "product" : tstr,
+     *         "model" : tstr,
+     *         "device" : tstr,
+     *         "vb_state" : "green" / "yellow" / "orange",    // Taken from the AVB values
+     *         "bootloader_state" : "locked" / "unlocked",    // Taken from the AVB values
+     *         "vbmeta_digest": bstr,                         // Taken from the AVB values
+     *         ? "os_version" : tstr,                         // Same as
+     *                                                        // android.os.Build.VERSION.release
+     *                                                        // Not optional for TEE.
+     *         "system_patch_level" : uint,                   // YYYYMMDD
+     *         "boot_patch_level" : uint,                     // YYYYMMDD
+     *         "vendor_patch_level" : uint,                   // YYYYMMDD
+     *         "version" : 2,                                 // The CDDL schema version.
+     *         "security_level" : "tee" / "strongbox",
+     *         "fused": 1 / 0,  // 1 if secure boot is enforced for the processor that the IRPC
+     *                          // implementation is contained in. 0 otherwise.
      *     }
      */
     byte[] deviceInfo;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
index 62a48e9..ad97443 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
@@ -37,10 +37,10 @@
      *
      *     PublicKey = {               // COSE_Key
      *         1 : 2,                  // Key type : EC2
-     *         3 : -8                  // Algorithm : ES256
-     *         -1 : 6,                 // Curve : P256
-     *         -2 : bstr               // X coordinate, little-endian
-     *         -3 : bstr               // Y coordinate, little-endian
+     *         3 : -7,                 // Algorithm : ES256
+     *         -1 : 1,                 // Curve : P256
+     *         -2 : bstr,              // X coordinate, little-endian
+     *         -3 : bstr,              // Y coordinate, little-endian
      *         ? -70000 : nil          // Presence indicates this is a test key.  If set, K_mac is
      *                                 // all zeros.
      *     },
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 24cdbc1..a14fc88 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -169,7 +169,6 @@
      *     PubKeyEd25519 = {                // COSE_Key
      *         1 : 1,                         // Key type : octet key pair
      *         3 : AlgorithmEdDSA,            // Algorithm : EdDSA
-     *         4 : 2,                         // Ops: Verify
      *         -1 : 6,                        // Curve : Ed25519
      *         -2 : bstr                      // X coordinate, little-endian
      *     }
@@ -184,7 +183,6 @@
      *     PubKeyECDSA256 = {                 // COSE_Key
      *         1 : 2,                         // Key type : EC2
      *         3 : AlgorithmES256,            // Algorithm : ECDSA w/ SHA-256
-     *         4 : 2,                         // Ops: Verify
      *         -1 : 1,                        // Curve: P256
      *         -2 : bstr,                     // X coordinate
      *         -3 : bstr                      // Y coordinate
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 2d2d701..91db3c8 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -75,6 +75,9 @@
     export_include_dirs: [
         ".",
     ],
+    export_static_lib_headers: [
+        "libkeymint_support",
+    ],
     static_libs: [
         "libgmock_ndk",
     ],
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 829780d..e2d75ce 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -57,6 +57,22 @@
 using namespace remote_prov;
 using namespace keymaster;
 
+std::set<std::string> getAllowedVbStates() {
+    return {"green", "yellow", "orange"};
+}
+
+std::set<std::string> getAllowedBootloaderStates() {
+    return {"locked", "unlocked"};
+}
+
+std::set<std::string> getAllowedSecurityLevels() {
+    return {"tee", "strongbox"};
+}
+
+std::set<std::string> getAllowedAttIdStates() {
+    return {"locked", "open"};
+}
+
 bytevec string_to_bytevec(const char* s) {
     const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
     return bytevec(p, p + strlen(s));
@@ -406,6 +422,8 @@
         ASSERT_TRUE(deviceInfoMap) << "Failed to parse deviceInfo: " << deviceInfoErrMsg;
         ASSERT_TRUE(deviceInfoMap->asMap());
 
+        checkDeviceInfo(deviceInfoMap->asMap(), deviceInfo.deviceInfo);
+
         auto& signingKey = bccContents->back().pubKey;
         auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey,
                                               cppbor::Array()  // SignedMacAad
@@ -432,6 +450,80 @@
         }
     }
 
+    void checkType(const cppbor::Map* devInfo, uint8_t majorType, std::string entryName) {
+        const auto& val = devInfo->get(entryName);
+        ASSERT_TRUE(val) << entryName << " does not exist";
+        ASSERT_EQ(val->type(), majorType) << entryName << " has the wrong type.";
+        switch (majorType) {
+            case cppbor::TSTR:
+                ASSERT_GT(val->asTstr()->value().size(), 0);
+                break;
+            case cppbor::BSTR:
+                ASSERT_GT(val->asBstr()->value().size(), 0);
+                break;
+            default:
+                break;
+        }
+    }
+
+    void checkDeviceInfo(const cppbor::Map* deviceInfo, bytevec deviceInfoBytes) {
+        const auto& version = deviceInfo->get("version");
+        ASSERT_TRUE(version);
+        ASSERT_TRUE(version->asUint());
+        RpcHardwareInfo info;
+        provisionable_->getHardwareInfo(&info);
+        ASSERT_EQ(version->asUint()->value(), info.versionNumber);
+        std::set<std::string> allowList;
+        switch (version->asUint()->value()) {
+            // These fields became mandated in version 2.
+            case 2:
+                checkType(deviceInfo, cppbor::TSTR, "brand");
+                checkType(deviceInfo, cppbor::TSTR, "manufacturer");
+                checkType(deviceInfo, cppbor::TSTR, "product");
+                checkType(deviceInfo, cppbor::TSTR, "model");
+                checkType(deviceInfo, cppbor::TSTR, "device");
+                // TODO: Refactor the KeyMint code that validates these fields and include it here.
+                checkType(deviceInfo, cppbor::TSTR, "vb_state");
+                allowList = getAllowedVbStates();
+                ASSERT_NE(allowList.find(deviceInfo->get("vb_state")->asTstr()->value()),
+                          allowList.end());
+                checkType(deviceInfo, cppbor::TSTR, "bootloader_state");
+                allowList = getAllowedBootloaderStates();
+                ASSERT_NE(allowList.find(deviceInfo->get("bootloader_state")->asTstr()->value()),
+                          allowList.end());
+                checkType(deviceInfo, cppbor::BSTR, "vbmeta_digest");
+                checkType(deviceInfo, cppbor::UINT, "system_patch_level");
+                checkType(deviceInfo, cppbor::UINT, "boot_patch_level");
+                checkType(deviceInfo, cppbor::UINT, "vendor_patch_level");
+                checkType(deviceInfo, cppbor::UINT, "fused");
+                ASSERT_LT(deviceInfo->get("fused")->asUint()->value(), 2);  // Must be 0 or 1.
+                checkType(deviceInfo, cppbor::TSTR, "security_level");
+                allowList = getAllowedSecurityLevels();
+                ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
+                          allowList.end());
+                if (deviceInfo->get("security_level")->asTstr()->value() == "tee") {
+                    checkType(deviceInfo, cppbor::TSTR, "os_version");
+                }
+                break;
+            case 1:
+                checkType(deviceInfo, cppbor::TSTR, "security_level");
+                allowList = getAllowedSecurityLevels();
+                ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
+                          allowList.end());
+                if (version->asUint()->value() == 1) {
+                    checkType(deviceInfo, cppbor::TSTR, "att_id_state");
+                    allowList = getAllowedAttIdStates();
+                    ASSERT_NE(allowList.find(deviceInfo->get("att_id_state")->asTstr()->value()),
+                              allowList.end());
+                }
+                break;
+            default:
+                FAIL() << "Unrecognized version: " << version->asUint()->value();
+        }
+        ASSERT_EQ(deviceInfo->clone()->asMap()->canonicalize().encode(), deviceInfoBytes)
+                << "DeviceInfo ordering is non-canonical.";
+    }
+
     bytevec eekId_;
     size_t testEekLength_;
     EekChain testEekChain_;
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 0cbee51..35cb891 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -26,6 +26,11 @@
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
 
+constexpr uint32_t kBccPayloadIssuer = 1;
+constexpr uint32_t kBccPayloadSubject = 2;
+constexpr int32_t kBccPayloadSubjPubKey = -4670552;
+constexpr int32_t kBccPayloadKeyUsage = -4670553;
+
 bytevec kTestMacKey(32 /* count */, 0 /* byte value */);
 
 bytevec randomBytes(size_t numBytes) {
@@ -98,6 +103,18 @@
     return prodEek;
 }
 
+ErrMsgOr<bytevec> validatePayloadAndFetchPubKey(const cppbor::Map* payload) {
+    const auto& issuer = payload->get(kBccPayloadIssuer);
+    if (!issuer || !issuer->asTstr()) return "Issuer is not present or not a tstr.";
+    const auto& subject = payload->get(kBccPayloadSubject);
+    if (!subject || !subject->asTstr()) return "Subject is not present or not a tstr.";
+    const auto& keyUsage = payload->get(kBccPayloadKeyUsage);
+    if (!keyUsage || !keyUsage->asBstr()) return "Key usage is not present or not a bstr.";
+    const auto& serializedKey = payload->get(kBccPayloadSubjPubKey);
+    if (!serializedKey || !serializedKey->asBstr()) return "Key is not present or not a bstr.";
+    return serializedKey->asBstr()->value();
+}
+
 ErrMsgOr<bytevec> verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1,
                                              const bytevec& signingCoseKey, const bytevec& aad) {
     if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
@@ -126,18 +143,16 @@
         return "Unsupported signature algorithm";
     }
 
-    // TODO(jbires): Handle CWTs as the CoseSign1 payload in a less hacky way. Since the CWT payload
-    //               is extremely remote provisioning specific, probably just make a separate
-    //               function there.
     auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(payload);
     if (!parsedPayload) return payloadErrMsg + " when parsing key";
     if (!parsedPayload->asMap()) return "CWT must be a map";
-    auto serializedKey = parsedPayload->asMap()->get(-4670552)->clone();
-    if (!serializedKey || !serializedKey->asBstr()) return "Could not find key entry";
+    auto serializedKey = validatePayloadAndFetchPubKey(parsedPayload->asMap());
+    if (!serializedKey) {
+        return "CWT validation failed: " + serializedKey.moveMessage();
+    }
 
     bool selfSigned = signingCoseKey.empty();
-    auto key =
-            CoseKey::parseEd25519(selfSigned ? serializedKey->asBstr()->value() : signingCoseKey);
+    auto key = CoseKey::parseEd25519(selfSigned ? *serializedKey : signingCoseKey);
     if (!key) return "Bad signing key: " + key.moveMessage();
 
     bytevec signatureInput =
@@ -148,7 +163,7 @@
         return "Signature verification failed";
     }
 
-    return serializedKey->asBstr()->value();
+    return serializedKey.moveValue();
 }
 
 ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
@@ -156,8 +171,11 @@
 
     std::vector<BccEntryData> result;
 
+    const auto& devicePubKey = bcc->get(0);
+    if (!devicePubKey->asMap()) return "Invalid device public key at the 1st entry in the BCC";
+
     bytevec prevKey;
-    // TODO(jbires): Actually process the pubKey at the start of the new bcc entry
+
     for (size_t i = 1; i < bcc->size(); ++i) {
         const cppbor::Array* entry = bcc->get(i)->asArray();
         if (!entry || entry->size() != kCoseSign1EntryCount) {
@@ -177,6 +195,13 @@
 
         // This entry's public key is the signing key for the next entry.
         prevKey = payload.moveValue();
+        if (i == 1) {
+            auto [parsedRootKey, _, errMsg] = cppbor::parse(prevKey);
+            if (!parsedRootKey || !parsedRootKey->asMap()) return "Invalid payload entry in BCC.";
+            if (*parsedRootKey != *devicePubKey) {
+                return "Device public key doesn't match BCC root.";
+            }
+        }
     }
 
     return result;
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index f5fc066..ccc4172 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -250,8 +250,8 @@
         Result currRes = mSubHalList[i]->initialize(this, this, i);
         if (currRes != Result::OK) {
             result = currRes;
-            ALOGE("Subhal '%s' failed to initialize.", mSubHalList[i]->getName().c_str());
-            break;
+            ALOGE("Subhal '%s' failed to initialize with reason %" PRId32 ".",
+                  mSubHalList[i]->getName().c_str(), static_cast<int32_t>(currRes));
         }
     }
 
diff --git a/thermal/2.0/default/Android.bp b/thermal/2.0/default/Android.bp
index a63ffbc..f743ade 100644
--- a/thermal/2.0/default/Android.bp
+++ b/thermal/2.0/default/Android.bp
@@ -22,16 +22,26 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "android.hardware.thermal@2.0-service.xml",
+    srcs: ["android.hardware.thermal@2.0-service.xml"],
+}
+
+filegroup {
+    name: "android.hardware.thermal@2.0-service.rc",
+    srcs: ["android.hardware.thermal@2.0-service.rc"],
+}
+
 cc_binary {
     name: "android.hardware.thermal@2.0-service.mock",
     defaults: ["hidl_defaults"],
     relative_install_path: "hw",
     vendor: true,
-    init_rc: ["android.hardware.thermal@2.0-service.rc"],
-    vintf_fragments: ["android.hardware.thermal@2.0-service.xml"],
+    init_rc: [":android.hardware.thermal@2.0-service.rc"],
+    vintf_fragments: [":android.hardware.thermal@2.0-service.xml"],
     srcs: [
         "Thermal.cpp",
-        "service.cpp"
+        "service.cpp",
     ],
     shared_libs: [
         "libbase",
diff --git a/thermal/2.0/default/apex/Android.bp b/thermal/2.0/default/apex/Android.bp
new file mode 100644
index 0000000..914a3a8
--- /dev/null
+++ b/thermal/2.0/default/apex/Android.bp
@@ -0,0 +1,55 @@
+// Copyright (C) 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 {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.thermal.key",
+    public_key: "com.android.hardware.thermal.avbpubkey",
+    private_key: "com.android.hardware.thermal.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.thermal.certificate",
+    certificate: "com.android.hardware.thermal",
+}
+
+genrule {
+    name: "com.android.hardware.thermal.rc-gen",
+    srcs: [":android.hardware.thermal@2.0-service.rc"],
+    out: ["com.android.hardware.thermal.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.thermal.mock/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.thermal.rc",
+    src: ":com.android.hardware.thermal.rc-gen",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.thermal.mock",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.thermal.key",
+    certificate: ":com.android.hardware.thermal.certificate",
+    use_vndk_as_stable: true,
+    updatable: false,
+    soc_specific: true,
+    binaries: ["android.hardware.thermal@2.0-service.mock"],
+    prebuilts: ["com.android.hardware.thermal.rc"],
+    vintf_fragments: [":android.hardware.thermal@2.0-service.xml"],
+}
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey b/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey
new file mode 100644
index 0000000..8f7cf72
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.avbpubkey
Binary files differ
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.pem b/thermal/2.0/default/apex/com.android.hardware.thermal.pem
new file mode 100644
index 0000000..4ea6e85
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEApXL2prEKqnU/xHlYeZB55x5EOrVAsfBuyHN5xOgUY877UuDC
+xoX+DOYAkCDSwMPmBj/Q9E70lId1PXMeI3y0obgYpdFubqRsoGNcEq2zG811tr6J
+BAE/7mAI0a4VVFWtauBNTiP5G31hsRpZNTE/dyZxs20GEVQqdvtBlEAuebCt7VIb
+fCwXnPCXSiYQ9WyjU0dwHoZPuy02qBuq3v9NYt5J6lYiPDqTWmpYBFm+SIZvth/j
+HUcaU3p+BlUad0qLhA8HYTPPBwJq2uHbTXeFrWXngt+UPCdzYubyUjG4WmgHIfee
+zSvoTjud2Gaofnd4/PcE5jFTMYUJuz0D4E+8StZArw+xegfxGcvqFZ4gfKAO1Vha
+eQBhw94P2eieUfh9metQEyKZ+A24sxG0awtAUOgcwr/WNv2TgJoN8+56DhuPXOuO
+U2qeIZuIrmE5xmyzrzJsCx+5vRQA7A3kpxRo1ZCgbJlzMgdAQaRTe2rqxyyoeFQR
+HbxUdsM7ZwDLE62UlaTTZFoJ1wzvZmsIJdkdRg97zcc3R3kYnVehCxAZ1KdAKzq6
+bhrw/kNAVA0zUHhlhHWGDnJQ/rkGfjQ9GGhS51IJYgKEoQc5M9hSgZD3idic8hso
+63r/P2Wn4S78gwLigfpzsGD7RrusTbMIRkebwpHwAYpB8qIykrtUKfunLtMCAwEA
+AQKCAgEAjiKbv0ytaw9bfwD4f0cdUu5vkzgPok55/f8mh4ERs0UoKGUrL74BKTeX
+GDr6k9w4CvpcGuaRu+A7WlVBeR8zVxN/KUUo6CidoZR6jxlmm+YA0MQTlbs1Hyal
+rO0vKcqJNx4Hi6/f3Dv0519JcCck7Mm8OHbbFZwG9zyXdDNHOggNA6rcLer7Rjpy
+3qKhQxbXoT3oFnEwog8Pu5A5VWZjJyLswULKGo//81cU0nf+vvOvmPj/9jEVbs32
+4p3OJNmHziXTIzCNFOqAvhX2fzDFSNgY8hf9k0gZGshpOS+5vwFLz2SZqo2j/0G8
+MyLOcgdVi4zzSobpf8tZNuAOKnCVwxteV3Ddl0o+qAf4cQCAXtuEkJvFWpAxrX4m
+J7nDDuvcTjKMlnchlm6XxmP27YNTKA2w5uNfrJQV5LR3IDs77PFpNiKOwERka6MU
+WE1LnjAFTCDxujT29NfIjC9z0iOY45TYut4okesaK7woe6pfK2H0ouvE6mZ+Lb7Y
+qZphPb4e4DZZZAVoELVvWflm/VC/xmBMA9vtzpjuvRXD+iYjgxbHaiG2UANLWmTd
+vADLqBadlbp10AvyrjKxHUhAiZnJgaVKRXtw5qk8YrwZOwypEHCQjY41fJuRScWF
+pD58/PYOLtSdwewzTijXSVwwPeqL1JMdJ+KWFk5zI410DtmHwoECggEBANM5dHEj
+L4ZOCcgHVG7aCLah7f/0Za7BBiPsZFD0uRIzWFTd77st3v8ulMw1JQiO3+xmpL7e
+iOP+onuSEMKgNQqeX9WCnv6pL+mjg0of2IEcGnvCpmfUZRA2x/MlyJRrQ1vHGqkV
+oBIIWgCGmIAWuFbHPmkNYx7mAJymAfzShkVtMw29oiGYyubqx9cTjD0odeyScbhZ
+LuMt72O5QeNsPREX4SsSRAL+vZbz1+8iRI8Fon89csZym3hos3DA4QSml+FNHnLe
+YFD6AfU7pdn79YhhNkn4jE0BxLaEkXhMs8RRTU2Q3o990ZxrAZGQz4zqOm5sOIQT
+JaXFXxGvOwEysrMCggEBAMiFaTzkhJSLEmLEu0T3gNEC2d3jE9kt4Olv4mQmzD00
+AzDtkrkArLQCeG3CMn55oFcJRwr8gAEk7/f2mvJSoZQnw0J0tRI+QiHJG4zwdsQC
+UszqN89X8ef0yoobwVa31ZoWxK4/NvLO4GZQ6UUd9uni10jfYVWmwEwKBU61ihvT
+ntcZIXvROR6khxzLeXtglnsznnYcdYMPJUeN+cfK9/rL3V3jk1jes8y8XwYfxkUa
+99nEe1NkRCUznzKxvkRwnKunlMCEkZ5z4nNMlqEqiOlVEYgwKwNCP+qM7ZKUJg7t
+uOL91bqWFPj2qdzyUh0uP5V/dg2odnu0xSblKWhxI2ECggEBAKbZttJ8Idlsoath
+pt+d2c4yoadTLlNZ5HjSDfgpKFxpNLhtTCbGuGVJLX8V5/gXrGi4OCER9n5rMXx9
+SEIFfYCy1C77bI7rpI5hfJ88ArESOxVSEFLqYx7otw+p5AThqibAY533GCfGcxoB
+OEvOJrVd1D31tju9IfSb6ewFfM0w0mhjSMRTRswb39pUda4F3QkQMUaXJEOOkJBs
+0dBNOvvaqiJ03kajZa3tVsBuiEuV/uOV7ak29Pqrcjt6EQW0dzsgyRGh+eFda9iE
+0qEbt7uQVusdq+5UnEg09hhaNpK4SmEgM76Te9WcbXPIOTst9xQs5oPmABIvk8aL
+bgenPaMCggEAX9EAHIzFnYVm37NKGQZ7k2RdXt2nGlwF4QYJk/nGFmjILZUYSza7
+T7jueuQU5MKRj4VrYSCOuf1AfahlGe3KL9VgRF0oOPNu/l3uwEYXOkox7qDs0jMf
+8MrUDXJ9zEZD10GR8gFa7GNWbw2yqchLuC8g2D2FcTwhHzSanKW6vNk+SWJE0bmE
+JdRQi73e6smYnn5n9eBbdqjCE5MQDBw8qqbHvJmGSyz/lZFdhrugLl1YmcJ9e7ep
+qG0mYT71wBZfhtapCeVO//w39Qhf4dtFWNnBauY5Z3E8wYNd8nDATtnhQvYwLtyQ
+YPbc7CsOecsjrvgdHSGmnC4hFxjh1HpbgQKCAQBzEr35CFQpUfGsu06SqRrxp7mb
+BfQzLmqnt+ZLu21H/YjVbamMXNjbJFSdtFLxAK/s9vFGQzEWWEYia2pRZejlCXhQ
+RO+TREJ4rm4Erfdh+zS9z8MZlxe2ybIMs260XxjZ0gEltRtJ6P14zLBlChi/rQEY
+tGrOpfjvLc1Lryaucwj7snDLtMfyqvemAUmuJNn/6IEMuG4DcdtJ3Whh7t3xKfO0
+Hc71Oh7F30okQQ6Ctiwp1T77Y1EXlRJrUtpf1sLxeItP6/r3WXLNaiFdKqGJxiCM
+Gw11oUcBA9bvfAzeJIpVVbLtGPNOp4J1XpkgFcWzsTM+ZpxWwbj4yJL6rSN2
+-----END RSA PRIVATE KEY-----
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.pk8 b/thermal/2.0/default/apex/com.android.hardware.thermal.pk8
new file mode 100644
index 0000000..3e5bf69
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.pk8
Binary files differ
diff --git a/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem b/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem
new file mode 100644
index 0000000..048e69a
--- /dev/null
+++ b/thermal/2.0/default/apex/com.android.hardware.thermal.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8UCFFWeg2KJX/fyAqZPcKaFS61/a3GiMA0GCSqGSIb3DQEBCwUAMIGp
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
+LmFuZHJvaWQuaGFyZHdhcmUudGhlcm1hbDAgFw0yMTExMTcxODE3MjRaGA80NzU5
+MTAxNDE4MTcyNFowgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
+VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
+MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5oYXJkd2FyZS50aGVybWFsMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2W8QhCKX0WoS5jhIWbWBoKulD6XhKASA
+CL0oU6Uci0U6id2m++ou/T0aHSlliS9kT1NEABNwbLeTDa9h1qg1lbajRzXbvzEz
+EvZYT+dlgYFNZ9zaVCIlMapoiN+nrM/Rs24UBjJrZu1B39+IcE5ciQz69PgrLKWF
+vFEdYzxWI246azOVr3fvdelQg+CyPgiGObVAGOHhAidvsjg4FssKnADzn+JNlTt6
+b9P65xUQErut8hz9YdLtfZ096iwe8eEpsMOQwCNdKNXVCcNjQWkOwRaU+0awHoH1
+4mArvF7yyvJxqzkNaR03BPqXAHPIAPu6xdfA19+HVIiz6bLEZ1mfCM6edXByCWZu
+K8o54OZph71r15ncv4DVd+cnBjNvBvfdlJSeGjSreFkUo5NkfAwqdmLfZx6CedHI
+sLx7X8vPYolQnR4UEvaX6yeNN0gs8Dd6ePMqOEiwWFVASD+cbpcUrp09uzlDStGV
+1DPx/9J2kw8eXPMqOSGThkLWuUMUFojyh7bNlL16oYmEeZW6/OOXCOXzAQgJ7NIs
+DA1/H2w1HMHWgSfF4y+Es2CiqcgVFOIU/07b31Edw4v56pjx1CUpRpJZjDA1JJNo
+A4YCnpA6JWTxzUTmv21fEYyY+poA3CuzvCfZ80z9h/UFW98oM9GawGvK0i2pLudS
+RaZXWeil08cCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAj2gpn/IpAHQLDlI52WwL
+IDc5uzlf1BGseLZ8M8uuMiwvN00nOjunQQZEIbhH7+03GYyMzRhTTI3nWwmX4Fnq
+vC5sR68yNlu9gOAMXaAHo/Rw73ak7sv8xGbb2FeQsHaMKDQ2nqxP17SWdQ0xWa1u
+5qNurPOdAPOw77noZcT7yYX7lcrOKxPIekPJxyeOlp4bQSmabSRgYr70B7GybPlv
+K1gkgCBxl5RiVjVxLo+7ESHSAaGLy0S7F2v6PJ9oj15TovWQ0py2iBKZ6HReB7s/
+umnQqkwXDLudlNmoXIsgIYn8vKFTYpy1GSNJqhRSLfvLR6NtuU0iCTvg/X7oPmS1
+dWUdjVeO7ZVvIpO3gLLEe4maBEYF2sOlt3bRmzIHydORJtkfTt5tiZ4wR9RfJbkj
+iBiDbNiX010bZPTAXmgMbuJzQXZEXCBy0qKeS1cHwf9M8FDoiLajXepfZIp+6syt
+D4lZk4eAV141JL5PfABfdZWwT3cTgFIqCYpqrMQJIu+GHEjUwD2yNPi0I1/ydFCW
+CPDnzWjYCi6yVB8hss3ZFbvhfyJzdm3LivNVbLGK0+TG0EOAz6d2aQ0UjESgMD1A
+U8hLzQt7MiFSG0bt2cVx6SgCHeYUqMntbFELEAURWrhAfPLMJtAvFgKbEiZEAkkW
+pdDVh603aIp4LjVCfTYp/mQ=
+-----END CERTIFICATE-----
diff --git a/thermal/2.0/default/apex/file_contexts b/thermal/2.0/default/apex/file_contexts
new file mode 100644
index 0000000..e0d87c7
--- /dev/null
+++ b/thermal/2.0/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)?                                                    u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)?                                    u:object_r:vendor_configs_file:s0
+# binary
+/bin/hw/android\.hardware\.thermal@2\.0-service\.mock     u:object_r:hal_thermal_default_exec:s0
diff --git a/thermal/2.0/default/apex/manifest.json b/thermal/2.0/default/apex/manifest.json
new file mode 100644
index 0000000..ee44dc1
--- /dev/null
+++ b/thermal/2.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.thermal.mock",
+  "version": 1
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 8cb7e22..1606b7b 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -69,37 +69,6 @@
 // disable.
 bool waitForSupplicantStop() { return waitForSupplicantState(false); }
 
-// Helper function to initialize the driver and firmware to STA mode
-// using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
-    // Skip if wifi instance is not set.
-    if (wifi_instance_name == "") {
-        return;
-    }
-    if (getWifi(wifi_instance_name) != nullptr) {
-        sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
-        ChipModeId mode_id;
-        EXPECT_TRUE(configureChipToSupportIfaceType(
-            wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
-    } else {
-        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
-    }
-}
-
-// Helper function to deinitialize the driver and firmware
-// using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
-    // Skip if wifi instance is not set.
-    if (wifi_instance_name == "") {
-        return;
-    }
-    if (getWifi(wifi_instance_name) != nullptr) {
-        stopWifi(wifi_instance_name);
-    } else {
-        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
-    }
-}
-
 // Helper function to find any iface of the desired type exposed.
 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
                      ISupplicant::IfaceInfo* out_info) {
@@ -156,14 +125,46 @@
     SupplicantManager supplicant_manager;
 
     ASSERT_TRUE(supplicant_manager.StopSupplicant());
-    deInitilializeDriverAndFirmware(wifi_instance_name);
+    deInitializeDriverAndFirmware(wifi_instance_name);
     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
 }
 
+// Helper function to initialize the driver and firmware to STA mode
+// using the vendor HAL HIDL interface.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    // Skip if wifi instance is not set.
+    if (wifi_instance_name == "") {
+        return;
+    }
+    if (getWifi(wifi_instance_name) != nullptr) {
+        sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
+        ChipModeId mode_id;
+        EXPECT_TRUE(configureChipToSupportIfaceType(
+            wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA,
+            &mode_id));
+    } else {
+        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+    }
+}
+
+// Helper function to deinitialize the driver and firmware
+// using the vendor HAL HIDL interface.
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    // Skip if wifi instance is not set.
+    if (wifi_instance_name == "") {
+        return;
+    }
+    if (getWifi(wifi_instance_name) != nullptr) {
+        stopWifi(wifi_instance_name);
+    } else {
+        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+    }
+}
+
 void startSupplicantAndWaitForHidlService(
     const std::string& wifi_instance_name,
     const std::string& supplicant_instance_name) {
-    initilializeDriverAndFirmware(wifi_instance_name);
+    initializeDriverAndFirmware(wifi_instance_name);
 
     SupplicantManager supplicant_manager;
     ASSERT_TRUE(supplicant_manager.StartSupplicant());
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 22cea8c..7228623 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -42,6 +42,11 @@
     const std::string& wifi_instance_name,
     const std::string& supplicant_instance_name);
 
+// Used to initialize/deinitialize the driver and firmware at the
+// beginning and end of each test.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name);
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name);
+
 // Helper functions to obtain references to the various HIDL interface objects.
 // Note: We only have a single instance of each of these objects currently.
 // These helper functions should be modified to return vectors if we support
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 65f9652..8e142ec 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -33,11 +33,23 @@
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
+        "libvndksupport",
     ],
     static_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",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V1-ndk",
         "libwifi-system",
         "libwifi-system-iface",
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiV1_5TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
     ],
     test_suites: [
         "general-tests",
@@ -55,11 +67,23 @@
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
+        "libvndksupport",
     ],
     static_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",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V1-ndk",
         "libwifi-system",
         "libwifi-system-iface",
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiV1_5TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
     ],
     test_suites: [
         "general-tests",
@@ -77,11 +101,23 @@
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
+        "libvndksupport",
     ],
     static_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",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V1-ndk",
         "libwifi-system",
         "libwifi-system-iface",
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiV1_5TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
     ],
     test_suites: [
         "general-tests",
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 d9d8179..d5bdde2 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
@@ -165,8 +165,7 @@
    public:
     void SetUp() override {
         initializeService();
-        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
-            AServiceManager_waitForService(GetParam().c_str())));
+        supplicant_ = getSupplicant(GetParam().c_str());
         ASSERT_NE(supplicant_, nullptr);
         ASSERT_TRUE(supplicant_
                         ->setDebugParams(DebugLevel::EXCESSIVE,
@@ -180,13 +179,13 @@
             GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test.";
         }
 
-        EXPECT_TRUE(supplicant_->addP2pInterface(getP2pIfaceName(), &p2p_iface_)
+        EXPECT_TRUE(supplicant_->getP2pInterface(getP2pIfaceName(), &p2p_iface_)
                         .isOk());
         ASSERT_NE(p2p_iface_, nullptr);
     }
 
     void TearDown() override {
-        stopSupplicant();
+        stopSupplicantService();
         startWifiFramework();
     }
 
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 6e6955f..b24f502 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
@@ -197,21 +197,20 @@
    public:
     void SetUp() override {
         initializeService();
-        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
-            AServiceManager_waitForService(GetParam().c_str())));
+        supplicant_ = getSupplicant(GetParam().c_str());
         ASSERT_NE(supplicant_, nullptr);
         ASSERT_TRUE(supplicant_
                         ->setDebugParams(DebugLevel::EXCESSIVE,
                                          true,  // show timestamps
                                          true)
                         .isOk());
-        EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+        EXPECT_TRUE(supplicant_->getStaInterface(getStaIfaceName(), &sta_iface_)
                         .isOk());
         ASSERT_NE(sta_iface_, nullptr);
     }
 
     void TearDown() override {
-        stopSupplicant();
+        stopSupplicantService();
         startWifiFramework();
     }
 
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 3d8242b..a19b300 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
@@ -99,15 +99,14 @@
    public:
     void SetUp() override {
         initializeService();
-        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
-            AServiceManager_waitForService(GetParam().c_str())));
+        supplicant_ = getSupplicant(GetParam().c_str());
         ASSERT_NE(supplicant_, nullptr);
         ASSERT_TRUE(supplicant_
                         ->setDebugParams(DebugLevel::EXCESSIVE,
                                          true,  // show timestamps
                                          true)
                         .isOk());
-        EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+        EXPECT_TRUE(supplicant_->getStaInterface(getStaIfaceName(), &sta_iface_)
                         .isOk());
         ASSERT_NE(sta_iface_, nullptr);
         EXPECT_TRUE(sta_iface_->addNetwork(&sta_network_).isOk());
@@ -115,7 +114,7 @@
     }
 
     void TearDown() override {
-        stopSupplicant();
+        stopSupplicantService();
         startWifiFramework();
     }
 
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index b7e1a80..17e0394 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -19,8 +19,14 @@
 
 #include <VtsCoreUtil.h>
 #include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <hidl/ServiceManagement.h>
+#include <supplicant_hidl_test_utils.h>
 #include <wifi_system/supplicant_manager.h>
 
+using aidl::android::hardware::wifi::supplicant::IfaceInfo;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
 using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
 using android::wifi_system::SupplicantManager;
@@ -37,6 +43,14 @@
     return std::string(buffer.data());
 }
 
+std::string getWifiInstanceName() {
+    const std::vector<std::string> instances =
+        android::hardware::getAllHalInstanceNames(
+            ::android::hardware::wifi::V1_0::IWifi::descriptor);
+    EXPECT_NE(0, instances.size());
+    return instances.size() != 0 ? instances[0] : "";
+}
+
 bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface,
                       KeyMgmtMask expected) {
     KeyMgmtMask caps;
@@ -53,60 +67,44 @@
     return keyMgmtSupported(iface, filsMask);
 }
 
-bool waitForSupplicantState(bool is_running) {
+void startSupplicant() {
+    initializeDriverAndFirmware(getWifiInstanceName());
     SupplicantManager supplicant_manager;
-    int count = 50; /* wait at most 5 seconds for completion */
-    while (count-- > 0) {
-        if (supplicant_manager.IsSupplicantRunning() == is_running) {
-            return true;
-        }
-        usleep(100000);
-    }
-    LOG(ERROR) << "Supplicant not " << (is_running ? "running" : "stopped");
-    return false;
+    ASSERT_TRUE(supplicant_manager.StartSupplicant());
+    ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
 }
 
-bool waitForFrameworkReady() {
-    int waitCount = 15;
-    do {
-        // Check whether package service is ready or not.
-        if (!testing::checkSubstringInCommandOutput(
-                "/system/bin/service check package", ": not found")) {
-            return true;
-        }
-        LOG(INFO) << "Framework is not ready";
-        sleep(1);
-    } while (waitCount-- > 0);
-    return false;
-}
-
-bool waitForSupplicantStart() { return waitForSupplicantState(true); }
-
-bool waitForSupplicantStop() { return waitForSupplicantState(false); }
-
-void stopSupplicant() {
-    SupplicantManager supplicant_manager;
-    ASSERT_TRUE(supplicant_manager.StopSupplicant());
-    ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
-}
-
-bool startWifiFramework() {
-    std::system("svc wifi enable");
-    std::system("cmd wifi set-scan-always-available enabled");
-    return waitForSupplicantStart();
-}
-
-bool stopWifiFramework() {
-    std::system("svc wifi disable");
-    std::system("cmd wifi set-scan-always-available disabled");
-    return waitForSupplicantStop();
-}
+// Wrapper around the implementation in supplicant_hidl_test_util.
+void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
 
 void initializeService() {
     ASSERT_TRUE(stopWifiFramework());
     std::system("/system/bin/start");
     ASSERT_TRUE(waitForFrameworkReady());
-    stopSupplicant();
+    stopSupplicantService();
+    startSupplicant();
+}
+
+void addStaIface(const std::shared_ptr<ISupplicant> supplicant) {
+    ASSERT_TRUE(supplicant.get());
+    std::shared_ptr<ISupplicantStaIface> iface;
+    ASSERT_TRUE(supplicant->addStaInterface(getStaIfaceName(), &iface).isOk());
+}
+
+void addP2pIface(const std::shared_ptr<ISupplicant> supplicant) {
+    ASSERT_TRUE(supplicant.get());
+    std::shared_ptr<ISupplicantP2pIface> iface;
+    ASSERT_TRUE(supplicant->addP2pInterface(getP2pIfaceName(), &iface).isOk());
+}
+
+std::shared_ptr<ISupplicant> getSupplicant(const char* supplicant_name) {
+    std::shared_ptr<ISupplicant> supplicant = ISupplicant::fromBinder(
+        ndk::SpAIBinder(AServiceManager_waitForService(supplicant_name)));
+    addStaIface(supplicant);
+    if (testing::deviceSupportsFeature("android.hardware.wifi.direct")) {
+        addP2pIface(supplicant);
+    }
+    return supplicant;
 }
 
 #endif  // SUPPLICANT_TEST_UTILS_H
\ No newline at end of file