Merge changes from topic "iinterceptor"

* changes:
  Add VTS for Netlink Interceptor
  Add default implementation for Nlinterceptor
  Move interceptor AIDL definition
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 0d4775c6a..1bd6abe 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -7,17 +7,40 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+soong_config_module_type {
+    name: "android_hardware_audio_config_default",
+    module_type: "cc_defaults",
+    config_namespace: "android_hardware_audio",
+    bool_variables: [
+        "run_64bit",
+    ],
+    properties: ["compile_multilib"],
+}
+
+android_hardware_audio_config_default {
+    name: "android_hardware_audio_config_defaults",
+
+    soong_config_variables: {
+        run_64bit: {
+            conditions_default: {
+                // Prefer 32 bit as the binary must always be installed at the same
+                // location for init to start it and the build system does not support
+                // having two binaries installable to the same location even if they are
+                // not installed in the same build.
+                compile_multilib: "prefer32",
+            },
+            compile_multilib: "64",
+        },
+    },
+}
+
 cc_binary {
     name: "android.hardware.audio.service",
 
     init_rc: ["android.hardware.audio.service.rc"],
     relative_install_path: "hw",
     vendor: true,
-    // Prefer 32 bit as the binary must always be installed at the same
-    // location for init to start it and the build system does not support
-    // having two binaries installable to the same location even if they are
-    // not installed in the same build.
-    compile_multilib: "prefer32",
+
     srcs: ["service.cpp"],
 
     cflags: [
@@ -34,6 +57,10 @@
         "libutils",
         "libhardware",
     ],
+
+    defaults: [
+        "android_hardware_audio_config_defaults",
+    ],
 }
 
 // Legacy service name, use android.hardware.audio.service instead
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 898c22d..89585b0 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -90,6 +90,7 @@
         },
         {
             "Bluetooth Audio API",
+            "android.hardware.bluetooth.audio@2.2::IBluetoothAudioProvidersFactory",
             "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory",
             "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory",
         },
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 6b4dbc1..e3b98c9 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -36,9 +36,14 @@
 std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
     std::vector<DeviceConfigParameter> result;
     for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+        auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
         for (const auto& ioProfile : module->getOutputProfiles()) {
+            if (getCachedPolicyConfig()
+                        .getAttachedSinkDeviceForMixPort(moduleName, ioProfile->getName())
+                        .empty()) {
+                continue;  // no attached device
+            }
             for (const auto& profile : ioProfile->getAudioProfiles()) {
                 const auto& channels = profile->getChannels();
                 const auto& sampleRates = profile->getSampleRates();
@@ -94,9 +99,14 @@
 std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
     std::vector<DeviceConfigParameter> result;
     for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+        auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
         for (const auto& ioProfile : module->getInputProfiles()) {
+            if (getCachedPolicyConfig()
+                        .getAttachedSourceDeviceForMixPort(moduleName, ioProfile->getName())
+                        .empty()) {
+                continue;  // no attached device
+            }
             for (const auto& profile : ioProfile->getAudioProfiles()) {
                 const auto& channels = profile->getChannels();
                 const auto& sampleRates = profile->getSampleRates();
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 0cc6a5b..2759801 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -499,18 +499,10 @@
             return xsd::isLinearPcm(std::get<PARAM_CONFIG>(cfg).base.format)
                    // MMAP NOIRQ and HW A/V Sync profiles use special writing protocols.
                    &&
-                   std::find_if(flags.begin(), flags.end(),
-                                [](const auto& flag) {
-                                    return flag == toString(xsd::AudioInOutFlag::
-                                                                    AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) ||
-                                           flag == toString(xsd::AudioInOutFlag::
-                                                                    AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
-                                }) == flags.end() &&
-                   !getCachedPolicyConfig()
-                            .getAttachedSinkDeviceForMixPort(
-                                    std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(cfg)),
-                                    std::get<PARAM_PORT_NAME>(cfg))
-                            .empty();
+                   std::find_if(flags.begin(), flags.end(), [](const auto& flag) {
+                       return flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) ||
+                              flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+                   }) == flags.end();
         });
         return pcmParams;
     }();
@@ -677,20 +669,13 @@
                            // reading h/w hotword might require Soundtrigger to be active.
                            &&
                            std::find_if(
-                                   flags.begin(), flags.end(),
-                                   [](const auto& flag) {
+                                   flags.begin(), flags.end(), [](const auto& flag) {
                                        return flag == toString(
                                                               xsd::AudioInOutFlag::
                                                                       AUDIO_INPUT_FLAG_MMAP_NOIRQ) ||
                                               flag == toString(xsd::AudioInOutFlag::
                                                                        AUDIO_INPUT_FLAG_HW_HOTWORD);
-                                   }) == flags.end() &&
-                           !getCachedPolicyConfig()
-                                    .getAttachedSourceDeviceForMixPort(
-                                            std::get<PARAM_DEVICE_NAME>(
-                                                    std::get<PARAM_DEVICE>(cfg)),
-                                            std::get<PARAM_PORT_NAME>(cfg))
-                                    .empty();
+                                   }) == flags.end();
                 });
         return pcmParams;
     }();
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 8c92cbd..42bf1d3 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -95,11 +95,16 @@
 std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
     std::vector<DeviceConfigParameter> result;
     for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+        auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
         if (!module || !module->getFirstMixPorts()) break;
         for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
             if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
+            if (getCachedPolicyConfig()
+                        .getAttachedSinkDeviceForMixPort(moduleName, mixPort.getName())
+                        .empty()) {
+                continue;  // no attached device
+            }
             auto [flags, isOffload] = generateOutFlags(mixPort);
             for (const auto& profile : mixPort.getProfile()) {
                 if (!profile.hasFormat() || !profile.hasSamplingRates() ||
@@ -223,11 +228,16 @@
 std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
     std::vector<DeviceConfigParameter> result;
     for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+        auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
         if (!module || !module->getFirstMixPorts()) break;
         for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
             if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
+            if (getCachedPolicyConfig()
+                        .getAttachedSourceDeviceForMixPort(moduleName, mixPort.getName())
+                        .empty()) {
+                continue;  // no attached device
+            }
             std::vector<AudioInOutFlag> flags;
             if (mixPort.hasFlags()) {
                 std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index b99ed43..b280d7c 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -217,6 +217,7 @@
     data: [
         "tests/apm_config_no_vx.xml",
         "tests/apm_config_with_vx.xml",
+        "tests/apm_config_b_205808571_6_0.xml",
     ],
     test_config: "tests/HalAudioV6_0GeneratorTest.xml",
 }
@@ -246,6 +247,7 @@
         "tests/apm_config_no_vx_7_0.xml",
         "tests/apm_config_with_vx_7_0.xml",
         "tests/apm_config_b_204314749_7_0.xml",
+        "tests/apm_config_b_205808571_7_0.xml",
     ],
     test_config: "tests/HalAudioV7_0GeneratorTest.xml",
 }
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index a94041c..171d03f 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -76,6 +76,16 @@
     const std::set<std::string>& getModulesWithDevicesNames() const {
         return mModulesWithDevicesNames;
     }
+    std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
+                                                const std::string& mixPortName) const {
+        return findAttachedDevice(getAttachedDevices(moduleName),
+                                  getSinkDevicesForMixPort(moduleName, mixPortName));
+    }
+    std::string getAttachedSourceDeviceForMixPort(const std::string& moduleName,
+                                                  const std::string& mixPortName) const {
+        return findAttachedDevice(getAttachedDevices(moduleName),
+                                  getSourceDevicesForMixPort(moduleName, mixPortName));
+    }
     bool haveInputProfilesInModule(const std::string& name) const {
         auto module = getModuleFromName(name);
         return module && !module->getInputProfiles().empty();
@@ -92,6 +102,8 @@
                 for (const auto& module : hwModules) {
                     if (module->getDeclaredDevices().indexOf(device) >= 0) {
                         mModulesWithDevicesNames.insert(module->getName());
+                        mAttachedDevicesPerModule[module->getName()].push_back(
+                                device->getTagName());
                         break;
                     }
                 }
@@ -100,16 +112,64 @@
                 for (const auto& module : hwModules) {
                     if (module->getDeclaredDevices().indexOf(device) >= 0) {
                         mModulesWithDevicesNames.insert(module->getName());
+                        mAttachedDevicesPerModule[module->getName()].push_back(
+                                device->getTagName());
                         break;
                     }
                 }
             }
         }
     }
+    std::string findAttachedDevice(const std::vector<std::string>& attachedDevices,
+                                   const std::set<std::string>& possibleDevices) const {
+        for (const auto& device : attachedDevices) {
+            if (possibleDevices.count(device)) return device;
+        }
+        return {};
+    }
+    std::vector<std::string> getAttachedDevices(const std::string& moduleName) const {
+        if (auto iter = mAttachedDevicesPerModule.find(moduleName);
+            iter != mAttachedDevicesPerModule.end()) {
+            return iter->second;
+        }
+        return {};
+    }
+    std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
+                                                   const std::string& mixPortName) const {
+        std::set<std::string> result;
+        auto module = getModuleFromName(moduleName);
+        if (module != nullptr) {
+            for (const auto& route : module->getRoutes()) {
+                for (const auto& source : route->getSources()) {
+                    if (source->getTagName() == mixPortName) {
+                        result.insert(route->getSink()->getTagName());
+                    }
+                }
+            }
+        }
+        return result;
+    }
+    std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
+                                                     const std::string& mixPortName) const {
+        std::set<std::string> result;
+        auto module = getModuleFromName(moduleName);
+        if (module != nullptr) {
+            for (const auto& route : module->getRoutes()) {
+                if (route->getSink()->getTagName() == mixPortName) {
+                    const auto& sources = route->getSources();
+                    std::transform(sources.begin(), sources.end(),
+                                   std::inserter(result, result.end()),
+                                   [](const auto& source) { return source->getTagName(); });
+                }
+            }
+        }
+        return result;
+    }
 
     const std::string mConfigFileName;
     status_t mStatus = android::NO_INIT;
     std::string mFilePath;
     sp<const android::HwModule> mPrimaryModule = nullptr;
     std::set<std::string> mModulesWithDevicesNames;
+    std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule;
 };
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
index 0c85a05..0230447 100644
--- a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
@@ -24,6 +24,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="apm_config_no_vx.xml->/data/local/tmp/apm_config_no_vx.xml" />
         <option name="push" value="apm_config_with_vx.xml->/data/local/tmp/apm_config_with_vx.xml" />
+        <option name="push" value="apm_config_b_205808571_6_0.xml->/data/local/tmp/apm_config_b_205808571_6_0.xml" />
         <option name="push" value="HalAudioV6_0GeneratorTest->/data/local/tmp/HalAudioV6_0GeneratorTest" />
     </target_preparer>
 
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
index 3dc5b33..0d8abd3 100644
--- a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
@@ -25,6 +25,7 @@
         <option name="push" value="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
         <option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
         <option name="push" value="apm_config_b_204314749_7_0.xml->/data/local/tmp/apm_config_b_204314749_7_0.xml" />
+        <option name="push" value="apm_config_b_205808571_7_0.xml->/data/local/tmp/apm_config_b_205808571_7_0.xml" />
         <option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
     </target_preparer>
 
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml
new file mode 100644
index 0000000..0f7bf7f
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (c) 2016-2021, The Linux Foundation. All rights reserved
+     Not a Contribution.
+-->
+<!-- Copyright (C) 2015 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g. version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="true" call_screen_mode_supported="true"/>
+
+
+    <!-- Modules section:
+        There is one section per audio HW module present on the platform.
+        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+        The module names are the same as in current .conf file:
+                “primary”, “A2DP”, “remote_submix”, “USB”
+        Each module will 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.
+            "route": is defined by an attribute:
+                -"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 vis route
+        “attachedDevices”: permanently attached devices.
+        The attachedDevices section is a list of devices names. The names correspond to device names
+        defined in <devicePorts> section.
+        “defaultOutputDevice”: device to be used by default when no policy rule applies
+    -->
+    <modules>
+        <!-- Primary Audio HAL -->
+        <module name="primary" halVersion="2.0">
+            <attachedDevices>
+                <item>Earpiece</item>
+                <item>Speaker</item>
+                <item>Telephony Tx</item>
+                <item>Built-In Mic</item>
+                <item>Built-In Back Mic</item>
+                <item>FM Tuner</item>
+                <item>Telephony Rx</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="raw" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="haptics output" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+                </mixPort>
+                <mixPort name="deep_buffer" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="hifi_playback" role="source" />
+                <mixPort name="compress_passthrough" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                </mixPort>
+                <mixPort name="direct_pcm" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                  <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                </mixPort>
+                <mixPort name="compressed_offload" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                    <profile name="" format="AUDIO_FORMAT_MP3"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_FLAC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_ALAC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_APE"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_LC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_HE_V1"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS"
+                             samplingRates="32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS_HD"
+                             samplingRates="32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_WMA"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_WMA_PRO"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_VORBIS"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_LC"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V1"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V2"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                </mixPort>
+                <mixPort name="voice_tx" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="voip_rx" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="incall_music_uplink" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+                <mixPort name="fast input" role="sink"
+                         flags="AUDIO_INPUT_FLAG_FAST">
+                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+                <mixPort name="quad mic" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                        samplingRates="48000"
+                        channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+                </mixPort>
+                <mixPort name="voip_tx" role="sink"
+                         flags="AUDIO_INPUT_FLAG_VOIP_TX">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </mixPort>
+                <mixPort name="usb_surround_sound" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+                </mixPort>
+                <mixPort name="record_24" role="sink" maxOpenCount="2" maxActiveCount="2">
+                    <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+                </mixPort>
+                <mixPort name="voice_rx" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+                <mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
+                </mixPort>
+                <mixPort name="hifi_input" role="sink" />
+            </mixPorts>
+
+            <devicePorts>
+                <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
+                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
+                </devicePort>
+                <devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
+                </devicePort>
+                <devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
+                </devicePort>
+                <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
+                </devicePort>
+
+                <!-- Input devices declaration, i.e. Source DEVICE PORT -->
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
+                </devicePort>
+                <devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source">
+                </devicePort>
+                <devicePort tagName="A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source"
+                            encodedFormats="VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+
+            </devicePorts>
+            <!-- route declaration, i.e. list all available sources for a given sink -->
+            <routes>
+                <route type="mix" sink="Earpiece"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Speaker"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Wired Headset"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Wired Headphones"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Line"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="HDMI"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,compress_passthrough,voip_rx,haptics output"/>
+                <route type="mix" sink="Proxy"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,haptics output"/>
+                <route type="mix" sink="FM"
+                       sources="primary output"/>
+                <route type="mix" sink="BT SCO"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT SCO Headset"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT SCO Car Kit"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="USB Device Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+                <route type="mix" sink="USB Headset Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+                <route type="mix" sink="Telephony Tx"
+                       sources="voice_tx,incall_music_uplink"/>
+                <route type="mix" sink="voice_rx"
+                       sources="Telephony Rx"/>
+                <route type="mix" sink="primary input"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,A2DP In"/>
+                <route type="mix" sink="usb_surround_sound"
+                       sources="USB Device In,USB Headset In"/>
+                <route type="mix" sink="fast input"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+                <route type="mix" sink="quad mic"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+                <route type="mix" sink="voip_tx"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+                <route type="mix" sink="record_24"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,A2DP In"/>
+                <route type="mix" sink="mmap_no_irq_in"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In,USB Headset In"/>
+                <route type="mix" sink="BT A2DP Out"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT A2DP Headphones"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT A2DP Speaker"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="hifi_input" sources="USB Device In,USB Headset In" />
+            </routes>
+
+        </module>
+
+        <!-- A2DP Audio HAL -->
+        <module name="a2dp" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="a2dp input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+            </mixPorts>
+
+            <devicePorts>
+                <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+            </devicePorts>
+
+            <routes>
+                <route type="mix" sink="a2dp input"
+                       sources="BT A2DP In"/>
+            </routes>
+        </module>
+
+        <!-- Usb Audio HAL -->
+        <module name="usb" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="usb_accessory output" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="USB Host Out"
+                       sources="usb_accessory output"/>
+            </routes>
+        </module>
+
+        <!-- Remote Submix Audio HAL -->
+        <!-- <xi:include href="/vendor/etc/r_submix_audio_policy_configuration.xml"/> -->
+
+        <!-- Bluetooth Audio HAL for hearing aid -->
+        <!-- <xi:include href="/vendor/etc/bluetooth_qti_hearing_aid_audio_policy_configuration.xml"/> -->
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section -->
+
+    <!-- <xi:include href="/vendor/etc/audio_policy_volumes.xml"/> -->
+    <!-- <xi:include href="/vendor/etc/default_volume_tables.xml"/> -->
+
+    <!-- End of Volume section -->
+
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml
new file mode 100644
index 0000000..16427b6
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (c) 2016-2021, The Linux Foundation. All rights reserved
+     Not a Contribution.
+-->
+<!-- Copyright (C) 2015 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.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g. version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="true" call_screen_mode_supported="true"/>
+
+
+    <!-- Modules section:
+        There is one section per audio HW module present on the platform.
+        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+        The module names are the same as in current .conf file:
+                “primary”, “A2DP”, “remote_submix”, “USB”
+        Each module will 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.
+            "route": is defined by an attribute:
+                -"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 vis route
+        “attachedDevices”: permanently attached devices.
+        The attachedDevices section is a list of devices names. The names correspond to device names
+        defined in <devicePorts> section.
+        “defaultOutputDevice”: device to be used by default when no policy rule applies
+    -->
+    <modules>
+        <!-- Primary Audio HAL -->
+        <module name="primary" halVersion="2.0">
+            <attachedDevices>
+                <item>Earpiece</item>
+                <item>Speaker</item>
+                <item>Telephony Tx</item>
+                <item>Built-In Mic</item>
+                <item>Built-In Back Mic</item>
+                <item>FM Tuner</item>
+                <item>Telephony Rx</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="raw" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_RAW">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="haptics output" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+                </mixPort>
+                <mixPort name="deep_buffer" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="hifi_playback" role="source" />
+                <mixPort name="compress_passthrough" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                </mixPort>
+                <mixPort name="direct_pcm" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                  <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                </mixPort>
+                <mixPort name="compressed_offload" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                    <profile name="" format="AUDIO_FORMAT_MP3"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_FLAC"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_ALAC"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_APE"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_LC"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_HE_V1"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS"
+                             samplingRates="32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS_HD"
+                             samplingRates="32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_WMA"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_WMA_PRO"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_VORBIS"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_LC"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V1"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V2"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+                </mixPort>
+                <mixPort name="voice_tx" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="voip_rx" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_VOIP_RX">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="incall_music_uplink" role="source"
+                        flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+                <mixPort name="fast input" role="sink"
+                         flags="AUDIO_INPUT_FLAG_FAST">
+                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                              samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                              channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+                <mixPort name="quad mic" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                        samplingRates="48000"
+                        channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+                </mixPort>
+                <mixPort name="voip_tx" role="sink"
+                         flags="AUDIO_INPUT_FLAG_VOIP_TX">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </mixPort>
+                <mixPort name="usb_surround_sound" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+                </mixPort>
+                <mixPort name="record_24" role="sink" maxOpenCount="2" maxActiveCount="2">
+                    <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+                </mixPort>
+                <mixPort name="voice_rx" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+                <mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3"/>
+                </mixPort>
+                <mixPort name="hifi_input" role="sink" />
+            </mixPorts>
+
+            <devicePorts>
+                <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
+                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
+                </devicePort>
+                <devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
+                </devicePort>
+                <devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
+                </devicePort>
+                <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
+                </devicePort>
+
+                <!-- Input devices declaration, i.e. Source DEVICE PORT -->
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                </devicePort>
+                <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
+                </devicePort>
+                <devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source">
+                </devicePort>
+                <devicePort tagName="A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source"
+                            encodedFormats="VX_AUDIO_FORMAT_LC3">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+
+            </devicePorts>
+            <!-- route declaration, i.e. list all available sources for a given sink -->
+            <routes>
+                <route type="mix" sink="Earpiece"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Speaker"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Wired Headset"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Wired Headphones"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="Line"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+                <route type="mix" sink="HDMI"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,compress_passthrough,voip_rx,haptics output"/>
+                <route type="mix" sink="Proxy"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,haptics output"/>
+                <route type="mix" sink="FM"
+                       sources="primary output"/>
+                <route type="mix" sink="BT SCO"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT SCO Headset"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT SCO Car Kit"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="USB Device Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+                <route type="mix" sink="USB Headset Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+                <route type="mix" sink="Telephony Tx"
+                       sources="voice_tx,incall_music_uplink"/>
+                <route type="mix" sink="voice_rx"
+                       sources="Telephony Rx"/>
+                <route type="mix" sink="primary input"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,A2DP In"/>
+                <route type="mix" sink="usb_surround_sound"
+                       sources="USB Device In,USB Headset In"/>
+                <route type="mix" sink="fast input"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+                <route type="mix" sink="quad mic"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+                <route type="mix" sink="voip_tx"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+                <route type="mix" sink="record_24"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,A2DP In"/>
+                <route type="mix" sink="mmap_no_irq_in"
+                       sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In,USB Headset In"/>
+                <route type="mix" sink="BT A2DP Out"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT A2DP Headphones"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="BT A2DP Speaker"
+                       sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+                <route type="mix" sink="hifi_input" sources="USB Device In,USB Headset In" />
+            </routes>
+
+        </module>
+
+        <!-- A2DP Audio HAL -->
+        <module name="a2dp" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="a2dp input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+            </mixPorts>
+
+            <devicePorts>
+                <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+            </devicePorts>
+
+            <routes>
+                <route type="mix" sink="a2dp input"
+                       sources="BT A2DP In"/>
+            </routes>
+        </module>
+
+        <!-- Usb Audio HAL -->
+        <module name="usb" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="usb_accessory output" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="USB Host Out"
+                       sources="usb_accessory output"/>
+            </routes>
+        </module>
+
+        <!-- Remote Submix Audio HAL -->
+
+        <!-- Bluetooth Audio HAL for hearing aid -->
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section -->
+
+    <!-- End of Volume section -->
+
+</audioPolicyConfiguration>
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 7caa712..3fdd8e6 100644
--- a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -131,8 +131,43 @@
 // clang-format off
 INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
                          ::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"
-#if MAJOR_VERSION == 7
+#if MAJOR_VERSION == 6
+                                         , "apm_config_b_205808571_6_0.xml"
+#elif MAJOR_VERSION == 7
                                          , "apm_config_b_204314749_7_0.xml"
+                                         , "apm_config_b_205808571_7_0.xml"
 #endif
                                            ));
 // clang-format on
+
+TEST(GeneratorsDeviceTest, AttachedDevicesOnly) {
+    static const std::string kTestFile =
+            "apm_config_b_205808571_" STRINGIFY(MAJOR_VERSION) "_0.xml";
+    ASSERT_TRUE(PolicyConfigManager::getInstance().init(kDataDir, kTestFile));
+    EXPECT_NE(nullptr, getCachedPolicyConfig().getPrimaryModule());
+    const auto allInConfigs = generateInputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+    EXPECT_FALSE(allInConfigs.empty());
+    for (const auto& configParam : allInConfigs) {
+        const AudioConfig& config = std::get<PARAM_CONFIG>(configParam);
+        // The config contains multichannel masks for mixPort connected to
+        // input devicePorts that are not attached. These multichannel masks must
+        // not appear among generated masks.
+        const uint32_t channelCount =
+#if MAJOR_VERSION == 6
+                audio_channel_count_from_in_mask(
+                        static_cast<audio_channel_mask_t>(config.channelMask));
+#elif MAJOR_VERSION == 7
+                xsd::getChannelCount(config.base.channelMask);
+#endif
+        EXPECT_TRUE(channelCount <= 4) << "Unexpected channel count: " << channelCount << " " <<
+#if MAJOR_VERSION == 6
+                ::testing::PrintToString(config.format) << ", "
+                                       << ::testing::PrintToString(config.sampleRateHz) << ", "
+                                       << ::testing::PrintToString(config.channelMask);
+#elif MAJOR_VERSION == 7
+                ::testing::PrintToString(config.base.format) << ", "
+                                       << ::testing::PrintToString(config.base.sampleRateHz) << ", "
+                                       << ::testing::PrintToString(config.base.channelMask);
+#endif
+    }
+}
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 3696351..ff6f3be 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -20,6 +20,9 @@
     },
     {
       "name": "FakeUserHalTest"
+    },
+    {
+      "name": "DefaultVehicleHalTest"
     }
   ]
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 54c65ba..22c690c 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable CreateUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo newUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index 6126f99..7d0196b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable CreateUserResponse {
   int requestId;
   android.hardware.automotive.vehicle.CreateUserStatus status = android.hardware.automotive.vehicle.CreateUserStatus.SUCCESS;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 177966b..d88cd8b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 5ecf4dd..a7df2ff 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueRequests {
   android.hardware.automotive.vehicle.GetValueRequest[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
index 60c46e4..25f3575 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
index 778ba8e..4c365b1 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueResults {
   android.hardware.automotive.vehicle.GetValueResult[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index c2c2500..a4c048a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable InitialUserInfoRequest {
   int requestId;
   android.hardware.automotive.vehicle.InitialUserInfoRequestType requestType = android.hardware.automotive.vehicle.InitialUserInfoRequestType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index ffb1781..f0e1612 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable InitialUserInfoResponse {
   int requestId;
   android.hardware.automotive.vehicle.InitialUserInfoResponseAction action = android.hardware.automotive.vehicle.InitialUserInfoResponseAction.DEFAULT;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
index e553d60..e7b0a13 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable RawPropValues {
   int[] int32Values = {};
   float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 6861309..74457b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable RemoveUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo removedUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
index d6cddb6..6a65307 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
index ea9ac9a..15fd7ea 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueRequests {
   android.hardware.automotive.vehicle.SetValueRequest[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
index 6c25bc8..ec5fabb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
index 65ff8f0..47f1656 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueResults {
   android.hardware.automotive.vehicle.SetValueResult[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index dcefd09..91e7c14 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SubscribeOptions {
   int propId;
   int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index bb18e02..3012b7a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SwitchUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index efc1911..8915d1b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SwitchUserResponse {
   int requestId;
   android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index a0f9879..a540f8e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationAssociation {
   android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
   android.hardware.automotive.vehicle.UserIdentificationAssociationValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 744030e..fe7fd6f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationGetRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo userInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index b47b003..3e2a257 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationResponse {
   int requestId;
   int numberAssociation;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index 5297349..57840fb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationSetAssociation {
   android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
   android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 725040d..db01b51 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationSetRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo userInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
index b99272b..f47d5e7 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserInfo {
   int userId = 0;
   int flags;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
index 7234316..edcef2e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UsersInfo {
   android.hardware.automotive.vehicle.UserInfo currentUser;
   int numberUsers;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 7a42ec8..b93a11b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
   int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 16ba6db..8602d2d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropConfig {
   int prop;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index e5d146d..04c8006 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropConfigs {
   android.hardware.automotive.vehicle.VehiclePropConfig[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 8b2e104..9835295 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropError {
   int propId;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6303d3a..9dcb10b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropErrors {
   android.hardware.automotive.vehicle.VehiclePropError[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index fc1ae53..c87379f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropValue {
   long timestamp;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index da8c60b..e09a6b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropValues {
   android.hardware.automotive.vehicle.VehiclePropValue[] payloads;
   long sharedMemoryId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 1f7c9cc..624e5a6 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable CreateUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index d011366..29db442 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable CreateUserResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 43a89d0..e5b3929 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 6601233..3bbb88c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueRequests {
     // A list of GetValueRequest to get if they fit the binder memory
     // limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
index b099a85..24c5757 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -20,6 +20,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
index 919e644..a8bfb2c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueResults {
     // The list of responses if they fit the binder memory limitation.
     GetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index 7879d44..c7ba836 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable InitialUserInfoRequest {
     /**
      * Arbitrary id used to map the HAL response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index 8be0c69..4c46fcb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable InitialUserInfoResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 5d8febd..9c6875b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -17,6 +17,7 @@
 package android.hardware.automotive.vehicle;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable RawPropValues {
     /**
      * This is used for properties of types VehiclePropertyType#INT
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 1a3d4dd..cb61da8 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable RemoveUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
index f2b0e27..625f901 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
index 5d6ad85..a690fa2 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueRequests {
     // The list of request if they fit the binder memory limitation.
     SetValueRequest[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
index a468f3b..b3feeaa 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.StatusCode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
index 6df9de0..9b0e505 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueResults {
     // The list of responses if they fit the binder memory limitation.
     SetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index bc7d84a..e68f7e3 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -20,6 +20,7 @@
  * Encapsulates information about subscription to vehicle property events.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SubscribeOptions {
     /** Property to subscribe */
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index 10858a4..320632c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -27,6 +27,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SwitchUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index d5d44e5..106386d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SwitchUserResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index cdd11bf..4af5f72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -23,6 +23,7 @@
  * Helper struct used when getting a user/identification association type.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationAssociation {
     UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
     UserIdentificationAssociationValue value = UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 58620ef..82580d7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationGetRequest {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index 06341c7..1487a70 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index fe5017f..bfb9544 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -23,6 +23,7 @@
  * Helper struct used when setting a user/identification association type.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationSetAssociation {
     UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
     UserIdentificationAssociationSetValue value = UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 13f3677..223ff08 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationSetRequest {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
index e4ecc4b..20c72bd 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -20,6 +20,7 @@
  * Information about a specific Android user.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserInfo {
     /**
      * System user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
index 77468b1..ede36f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -26,6 +26,7 @@
  * Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UsersInfo {
     /**
      * The current foreground user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
index 82f98d8..1031ebb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
@@ -23,6 +23,7 @@
      * This requests Android to enter its normal operating state.
      * This may be sent after the AP has reported
      * VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+     * VehicleApPowerStateReport#HIBERNATION_EXIT,
      * VehicleApPowerStateReport#SHUTDOWN_CANCELLED, or
      * VehicleApPowerStateReport#WAIT_FOR_VHAL.
      */
@@ -31,6 +32,7 @@
      * The power controller issues this request to shutdown the system.
      * This may be sent after the AP has reported
      * VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+     * VehicleApPowerStateReport#HIBERNATION_EXIT,
      * VehicleApPowerStateReport#ON,
      * VehicleApPowerStateReport#SHUTDOWN_CANCELLED,
      * VehicleApPowerStateReport#SHUTDOWN_POSTPONE,
@@ -59,6 +61,7 @@
      * Completes the shutdown process.
      * This may be sent after the AP has reported
      * VehicleApPowerStateReport#DEEP_SLEEP_ENTRY or
+     * VehicleApPowerStateReport#HIBERNATION_ENTRY or
      * VehicleApPowerStateReport#SHUTDOWN_START. The AP will not report new
      * state information after receiving this request.
      */
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b33dcbc..b44996d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -17,6 +17,7 @@
 package android.hardware.automotive.vehicle;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehicleAreaConfig {
     /**
      * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 5e0dbec..1b48f0b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -21,6 +21,7 @@
 import android.hardware.automotive.vehicle.VehiclePropertyChangeMode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropConfig {
     /** Property identifier */
     int prop;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index 98abdef..9c2d5f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropConfigs {
     // The list of vehicle property configs if they fit the binder memory
     // limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 1608977..2c31c72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.StatusCode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropError {
     // Property ID.
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6a77d35..10a164d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropErrors {
     // List of property set errors if they fit binder memory limitation.
     VehiclePropError[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index 37dac59..289f270 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -25,6 +25,7 @@
  * events.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropValue {
     /** Time is elapsed nanoseconds since boot */
     long timestamp;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index 1944f8e..df44fdb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropValues {
     // The list of vehicle properties if they fit the binder memory limitation.
     VehiclePropValue[] payloads;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index dfc2efc..dcd9208 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -22,10 +22,17 @@
     name: "FakeVehicleHardware",
     vendor: true,
     srcs: ["src/*.cpp"],
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
-    defaults: ["VehicleHalDefaults"],
+    defaults: [
+        "VehicleHalDefaults",
+        "FakeVehicleHardwareDefaults",
+    ],
+}
+
+cc_defaults {
+    name: "FakeVehicleHardwareDefaults",
+    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
     header_libs: [
         "IVehicleHardware",
         "VehicleHalDefaultConfig",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 104147a..5b2003e 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -62,27 +62,6 @@
 const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
 const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override";
 
-template <class T>
-StatusCode getErrorCode(const Result<T>& result) {
-    if (result.ok()) {
-        return StatusCode::OK;
-    }
-    return static_cast<StatusCode>(result.error().code());
-}
-
-template <class T>
-int getIntErrorCode(const Result<T>& result) {
-    return toInt(getErrorCode(result));
-}
-
-template <class T>
-std::string getErrorMsg(const Result<T>& result) {
-    if (result.ok()) {
-        return "";
-    }
-    return result.error().message();
-}
-
 }  // namespace
 
 void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 2b36c72..013d177 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -25,6 +25,7 @@
 #include <aidl/android/hardware/automotive/vehicle/FuelType.h>
 #include <aidl/android/hardware/automotive/vehicle/GetValueRequest.h>
 #include <aidl/android/hardware/automotive/vehicle/GetValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/GetValueResults.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -34,6 +35,7 @@
 #include <aidl/android/hardware/automotive/vehicle/PortLocationType.h>
 #include <aidl/android/hardware/automotive/vehicle/SetValueRequest.h>
 #include <aidl/android/hardware/automotive/vehicle/SetValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
 #include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 95e58c6..63eb747 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -18,6 +18,9 @@
 #define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleUtils_H_
 
 #include <VehicleHalTypes.h>
+
+#include <android-base/format.h>
+#include <android-base/result.h>
 #include <utils/Log.h>
 
 namespace android {
@@ -183,6 +186,60 @@
     return size;
 }
 
+template <class T>
+::aidl::android::hardware::automotive::vehicle::StatusCode getErrorCode(
+        const ::android::base::Result<T>& result) {
+    if (result.ok()) {
+        return ::aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+    }
+    return static_cast<::aidl::android::hardware::automotive::vehicle::StatusCode>(
+            result.error().code());
+}
+
+template <class T>
+int getIntErrorCode(const ::android::base::Result<T>& result) {
+    return toInt(getErrorCode(result));
+}
+
+template <class T>
+std::string getErrorMsg(const ::android::base::Result<T>& result) {
+    if (result.ok()) {
+        return "";
+    }
+    return result.error().message();
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+        const ::android::base::Result<T>& result,
+        ::aidl::android::hardware::automotive::vehicle::StatusCode status,
+        std::string additionalErrorMsg) {
+    if (result.ok()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            toInt(status),
+            fmt::format("{}, error: {}", additionalErrorMsg, getErrorMsg(result)).c_str());
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+        const ::android::base::Result<T>& result,
+        ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
+    return toScopedAStatus(result, status, "");
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
+    return toScopedAStatus(result, getErrorCode(result));
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result,
+                                     std::string additionalErrorMsg) {
+    return toScopedAStatus(result, getErrorCode(result), additionalErrorMsg);
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 0704107..79d3ebd 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -1,37 +1,68 @@
-// 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.
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 cc_binary {
     name: "android.hardware.automotive.vehicle-aidl-default-service",
-    defaults: ["VehicleHalDefaults"],
-    local_include_dirs: ["include"],
+    vendor: true,
+    defaults: [
+        "FakeVehicleHardwareDefaults",
+        "VehicleHalDefaults",
+        "android-automotive-large-parcelable-defaults",
+    ],
     vintf_fragments: ["vhal-default-service.xml"],
     init_rc: ["vhal-default-service.rc"],
-    vendor: true,
     relative_install_path: "hw",
-    srcs: ["src/*.cpp"],
+    srcs: ["src/VehicleService.cpp"],
+    static_libs: [
+        "DefaultVehicleHal",
+        "FakeVehicleHardware",
+        "VehicleHalUtils",
+        "android-automotive-large-parcelable-vendor-lib",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+}
+
+cc_library {
+    name: "DefaultVehicleHal",
+    vendor: true,
+    defaults: [
+        "VehicleHalDefaults",
+        "android-automotive-large-parcelable-defaults",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/ConnectedClient.cpp",
+        "src/DefaultVehicleHal.cpp",
+    ],
     static_libs: [
         "VehicleHalUtils",
+        "android-automotive-large-parcelable-vendor-lib",
+    ],
+    header_libs: [
+        "IVehicleHardware",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
new file mode 100644
index 0000000..43a9603
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
+
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
+#include <android-base/result.h>
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// A class to represent a binder client with a callback interface. Each callback function, e.g.
+// GetValues or SetValues for a specific binder client is a separate {@code ConnectedClient}.
+// For one {@code ConnectedClient}, we use one pending request pool to manage all pending requests,
+// so the request IDs must be unique for one client. We also manage a set of callback functions
+// for one client, e.g. timeoutCallback which could be passed to hardware.
+// This class is thread-safe.
+class ConnectedClient {
+  public:
+    ConnectedClient(
+            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+                    callback);
+
+    virtual ~ConnectedClient() = default;
+
+  protected:
+    const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+            mCallback;
+};
+
+// A class to represent a client that calls {@code IVehicle.setValues} or {@code
+// IVehicle.getValues}.
+template <class ResultType, class ResultsType>
+class GetSetValuesClient final : public ConnectedClient {
+  public:
+    GetSetValuesClient(
+            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+                    callback);
+
+    // Sends the results to this client.
+    void sendResults(const std::vector<ResultType>& results);
+
+    // Sends each result separately to this client. Each result would be sent through one callback
+    // invocation.
+    void sendResultsSeparately(const std::vector<ResultType>& results);
+
+    // Gets the callback to be called when the request for this client has finished.
+    std::shared_ptr<const std::function<void(std::vector<ResultType>)>> getResultCallback();
+
+  private:
+    // The following members are only initialized during construction.
+    std::shared_ptr<const std::function<void(std::vector<ResultType>)>> mResultCallback;
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 49c501e..43bdca2 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -17,14 +17,68 @@
 #ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
 
+#include <IVehicleHardware.h>
+#include <LargeParcelableBase.h>
+#include <VehicleUtils.h>
 #include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
+#include <android/binder_auto_utils.h>
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
 
 namespace android {
 namespace hardware {
 namespace automotive {
 namespace vehicle {
 
+// private namespace
+namespace defaultvehiclehal_impl {
+
+constexpr int INVALID_MEMORY_FD = -1;
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+        const ::android::base::Result<T>& result,
+        ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
+    if (result.ok()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(toInt(status),
+                                                                     getErrorMsg(result).c_str());
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
+    return toScopedAStatus(result, getErrorCode(result));
+}
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>& values, T2* output) {
+    auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
+            parcelableVectorToStableLargeParcelable(values);
+    if (!result.ok()) {
+        return toScopedAStatus(
+                result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
+    }
+    auto& fd = result.value();
+    if (fd == nullptr) {
+        output->payloads = values;
+    } else {
+        // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
+        // 'sharedMemoryFd' field.
+        output->sharedMemoryFd.set(fd->get());
+        *(fd->getR()) = INVALID_MEMORY_FD;
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+}  // namespace defaultvehiclehal_impl
+
 class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::vehicle::BnVehicle {
+  public:
+    explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
+
     ::ndk::ScopedAStatus getAllPropConfigs(
             ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
             override;
@@ -56,6 +110,14 @@
             const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
                     callback,
             int64_t sharedMemoryId) override;
+
+    IVehicleHardware* getHardware();
+
+  private:
+    const std::unique_ptr<IVehicleHardware> mVehicleHardware;
+    std::unordered_map<int32_t, ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
+            mConfigsByPropId;
+    std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile;
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
new file mode 100644
index 0000000..dcb15b9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_ParcelableUtils_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_ParcelableUtils_H_
+
+#include <LargeParcelableBase.h>
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>&& values, T2* output) {
+    auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
+            parcelableVectorToStableLargeParcelable(values);
+    if (!result.ok()) {
+        return toScopedAStatus(
+                result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
+    }
+    auto& fd = result.value();
+    if (fd == nullptr) {
+        // If we no longer needs values, move it inside the payloads to avoid copying.
+        output->payloads = std::move(values);
+    } else {
+        // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
+        // 'sharedMemoryFd' field.
+        output->sharedMemoryFd = std::move(*fd);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(const std::vector<T1>& values, T2* output) {
+    // Because 'values' is passed in as const reference, we have to do a copy here.
+    std::vector<T1> valuesCopy = values;
+
+    return vectorToStableLargeParcelable(std::move(valuesCopy), output);
+}
+
+template <class T1, class T2>
+::android::base::expected<std::vector<T1>, ::ndk::ScopedAStatus> stableLargeParcelableToVector(
+        const T2& largeParcelable) {
+    ::android::base::Result<std::optional<std::vector<T1>>> result =
+            ::android::automotive::car_binder_lib::LargeParcelableBase::
+                    stableLargeParcelableToParcelableVector<T1>(largeParcelable.sharedMemoryFd);
+
+    if (!result.ok()) {
+        return ::android::base::unexpected(toScopedAStatus(
+                result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INVALID_ARG,
+                "failed to parse large parcelable"));
+    }
+
+    if (!result.value().has_value()) {
+        return ::android::base::unexpected(
+                ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                        toInt(::aidl::android::hardware::automotive::vehicle::StatusCode::
+                                      INVALID_ARG),
+                        "empty request"));
+    }
+
+    return std::move(result.value().value());
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_ParcelableUtils_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
new file mode 100644
index 0000000..656dfaf
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConnectedClient.h"
+#include "ParcelableUtils.h"
+
+#include <VehicleHalTypes.h>
+
+#include <utils/Log.h>
+
+#include <inttypes.h>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::android::base::Result;
+using ::ndk::ScopedAStatus;
+
+// A function to call the specific callback based on results type.
+template <class T>
+ScopedAStatus callCallback(std::shared_ptr<IVehicleCallback> callback, const T& results);
+
+template <>
+ScopedAStatus callCallback<GetValueResults>(std::shared_ptr<IVehicleCallback> callback,
+                                            const GetValueResults& results) {
+    return callback->onGetValues(results);
+}
+
+template <>
+ScopedAStatus callCallback<SetValueResults>(std::shared_ptr<IVehicleCallback> callback,
+                                            const SetValueResults& results) {
+    return callback->onSetValues(results);
+}
+
+// Send a single GetValue/SetValue result through the callback.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResult(std::shared_ptr<IVehicleCallback> callback, const ResultType& result) {
+    ResultsType parcelableResults;
+    parcelableResults.payloads.resize(1);
+    parcelableResults.payloads[0] = result;
+    if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
+        !callbackStatus.isOk()) {
+        ALOGE("failed to call callback, error: %s, code: %d", callbackStatus.getMessage(),
+              callbackStatus.getServiceSpecificError());
+    }
+}
+
+// Send all the GetValue/SetValue results through callback, one result in each callback invocation.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResultsSeparately(std::shared_ptr<IVehicleCallback> callback,
+                                        const std::vector<ResultType>& results) {
+    for (const auto& result : results) {
+        sendGetOrSetValueResult<ResultType, ResultsType>(callback, result);
+    }
+}
+
+// Send all the GetValue/SetValue results through callback in a single callback invocation.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResults(std::shared_ptr<IVehicleCallback> callback,
+                              const std::vector<ResultType>& results) {
+    ResultsType parcelableResults;
+    ScopedAStatus status = vectorToStableLargeParcelable(results, &parcelableResults);
+    if (status.isOk()) {
+        if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
+            !callbackStatus.isOk()) {
+            ALOGE("failed to call callback, error: %s, code: %d", status.getMessage(),
+                  status.getServiceSpecificError());
+        }
+        return;
+    }
+    int statusCode = status.getServiceSpecificError();
+    ALOGE("failed to marshal result into large parcelable, error: "
+          "%s, code: %d",
+          status.getMessage(), statusCode);
+    sendGetOrSetValueResultsSeparately<ResultType, ResultsType>(callback, results);
+}
+
+// Specify the functions for GetValues and SetValues types.
+template void sendGetOrSetValueResult<GetValueResult, GetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const GetValueResult& result);
+template void sendGetOrSetValueResult<SetValueResult, SetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const SetValueResult& result);
+
+template void sendGetOrSetValueResults<GetValueResult, GetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const std::vector<GetValueResult>& results);
+template void sendGetOrSetValueResults<SetValueResult, SetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const std::vector<SetValueResult>& results);
+
+template void sendGetOrSetValueResultsSeparately<GetValueResult, GetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const std::vector<GetValueResult>& results);
+template void sendGetOrSetValueResultsSeparately<SetValueResult, SetValueResults>(
+        std::shared_ptr<IVehicleCallback> callback, const std::vector<SetValueResult>& results);
+
+}  // namespace
+
+ConnectedClient::ConnectedClient(std::shared_ptr<IVehicleCallback> callback)
+    : mCallback(callback) {}
+
+template <class ResultType, class ResultsType>
+GetSetValuesClient<ResultType, ResultsType>::GetSetValuesClient(
+        std::shared_ptr<IVehicleCallback> callback)
+    : ConnectedClient(callback) {
+    mResultCallback = std::make_shared<const std::function<void(std::vector<ResultType>)>>(
+            [callback](std::vector<ResultType> results) {
+                return sendGetOrSetValueResults<ResultType, ResultsType>(callback, results);
+            });
+}
+
+template <class ResultType, class ResultsType>
+std::shared_ptr<const std::function<void(std::vector<ResultType>)>>
+GetSetValuesClient<ResultType, ResultsType>::getResultCallback() {
+    return mResultCallback;
+}
+
+template <class ResultType, class ResultsType>
+void GetSetValuesClient<ResultType, ResultsType>::sendResults(
+        const std::vector<ResultType>& results) {
+    return sendGetOrSetValueResults<ResultType, ResultsType>(mCallback, results);
+}
+
+template <class ResultType, class ResultsType>
+void GetSetValuesClient<ResultType, ResultsType>::sendResultsSeparately(
+        const std::vector<ResultType>& results) {
+    return sendGetOrSetValueResultsSeparately<ResultType, ResultsType>(mCallback, results);
+}
+
+template class GetSetValuesClient<GetValueResult, GetValueResults>;
+template class GetSetValuesClient<SetValueResult, SetValueResults>;
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 5a31643..fd9e331 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -18,7 +18,11 @@
 
 #include <DefaultVehicleHal.h>
 
+#include <LargeParcelableBase.h>
 #include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+#include <android-base/result.h>
+#include <utils/Log.h>
 
 namespace android {
 namespace hardware {
@@ -28,12 +32,41 @@
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Result;
 using ::ndk::ScopedAStatus;
 
-ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs*) {
-    // TODO(b/200737967): implement this.
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware)
+    : mVehicleHardware(std::move(hardware)) {
+    auto configs = mVehicleHardware->getAllPropertyConfigs();
+    for (auto& config : configs) {
+        mConfigsByPropId[config.prop] = config;
+    }
+    auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(configs);
+    if (!result.ok()) {
+        ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+              getErrorMsg(result).c_str(), getIntErrorCode(result));
+        return;
+    }
+
+    if (result.value() != nullptr) {
+        mConfigFile = std::move(result.value());
+    }
+}
+
+ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
+    if (mConfigFile != nullptr) {
+        output->sharedMemoryFd.set(dup(mConfigFile->get()));
+        return ScopedAStatus::ok();
+    }
+    output->payloads.reserve(mConfigsByPropId.size());
+    for (const auto& [_, config] : mConfigsByPropId) {
+        output->payloads.push_back(config);
+    }
     return ScopedAStatus::ok();
 }
 
@@ -49,9 +82,15 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>&, VehiclePropConfigs*) {
-    // TODO(b/200737967): implement this.
-    return ScopedAStatus::ok();
+ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
+                                                VehiclePropConfigs* output) {
+    std::vector<VehiclePropConfig> configs;
+    for (int32_t prop : props) {
+        if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) {
+            configs.push_back(mConfigsByPropId[prop]);
+        }
+    }
+    return defaultvehiclehal_impl::vectorToStableLargeParcelable(configs, output);
 }
 
 ScopedAStatus DefaultVehicleHal::subscribe(const std::shared_ptr<IVehicleCallback>&,
@@ -72,6 +111,10 @@
     return ScopedAStatus::ok();
 }
 
+IVehicleHardware* DefaultVehicleHal::getHardware() {
+    return mVehicleHardware.get();
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
index 7c623ea..14224a5 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
@@ -17,15 +17,19 @@
 #define LOG_TAG "VehicleService"
 
 #include <DefaultVehicleHal.h>
+#include <FakeVehicleHardware.h>
 
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <utils/Log.h>
 
 using ::android::hardware::automotive::vehicle::DefaultVehicleHal;
+using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
 
 int main(int /* argc */, char* /* argv */[]) {
-    std::shared_ptr<DefaultVehicleHal> vhal = ndk::SharedRefBase::make<DefaultVehicleHal>();
+    std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
+    std::shared_ptr<DefaultVehicleHal> vhal =
+            ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
 
     ALOGI("Registering as service...");
     binder_exception_t err = AServiceManager_addService(vhal->asBinder().get(),
diff --git a/automotive/vehicle/aidl/impl/vhal/test/Android.bp b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
new file mode 100644
index 0000000..bf16475
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "DefaultVehicleHalTest",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "DefaultVehicleHal",
+        "VehicleHalUtils",
+        "android-automotive-large-parcelable-vendor-lib",
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    defaults: [
+        "VehicleHalDefaults",
+        "android-automotive-large-parcelable-defaults",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
new file mode 100644
index 0000000..ddd0c65
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConnectedClient.h"
+#include "MockVehicleCallback.h"
+
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+class ConnectedClientTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
+        mCallbackClient = IVehicleCallback::fromBinder(mCallback->asBinder());
+    }
+
+    std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
+
+    MockVehicleCallback* getCallback() { return mCallback.get(); }
+
+  protected:
+    using GetValuesClient = GetSetValuesClient<GetValueResult, GetValueResults>;
+    using SetValuesClient = GetSetValuesClient<SetValueResult, SetValueResults>;
+
+  private:
+    std::shared_ptr<MockVehicleCallback> mCallback;
+    std::shared_ptr<IVehicleCallback> mCallbackClient;
+};
+
+TEST_F(ConnectedClientTest, testSendGetValueResults) {
+    std::vector<GetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 0,
+                                                           },
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 1,
+                                                           },
+                                           }};
+
+    GetValuesClient client(getCallbackClient());
+
+    client.sendResults(results);
+
+    auto maybeGetValueResults = getCallback()->nextGetValueResults();
+    ASSERT_TRUE(maybeGetValueResults.has_value());
+    ASSERT_EQ(maybeGetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendGetValueResultsSeparately) {
+    std::vector<GetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 0,
+                                                           },
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 1,
+                                                           },
+                                           }};
+
+    GetValuesClient client(getCallbackClient());
+
+    client.sendResultsSeparately(results);
+
+    for (auto& result : results) {
+        auto maybeGetValueResults = getCallback()->nextGetValueResults();
+        EXPECT_TRUE(maybeGetValueResults.has_value());
+        if (!maybeGetValueResults.has_value()) {
+            continue;
+        }
+        EXPECT_EQ(maybeGetValueResults.value().payloads, std::vector<GetValueResult>({result}));
+    }
+}
+
+TEST_F(ConnectedClientTest, testGetValuesGnResultCallback) {
+    std::vector<GetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 0,
+                                                           },
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                                   .prop =
+                                                           VehiclePropValue{
+                                                                   .prop = 1,
+                                                           },
+                                           }};
+
+    GetValuesClient client(getCallbackClient());
+
+    (*(client.getResultCallback()))(results);
+
+    auto maybeGetValueResults = getCallback()->nextGetValueResults();
+    ASSERT_TRUE(maybeGetValueResults.has_value());
+    ASSERT_EQ(maybeGetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendSetValueResults) {
+    std::vector<SetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                           }};
+
+    SetValuesClient client(getCallbackClient());
+
+    client.sendResults(results);
+
+    auto maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value());
+    ASSERT_EQ(maybeSetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendSetValueResultsSeparately) {
+    std::vector<SetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                           }};
+
+    SetValuesClient client(getCallbackClient());
+
+    client.sendResultsSeparately(results);
+
+    for (auto& result : results) {
+        auto maybeSetValueResults = getCallback()->nextSetValueResults();
+        EXPECT_TRUE(maybeSetValueResults.has_value());
+        if (!maybeSetValueResults.has_value()) {
+            continue;
+        }
+        EXPECT_EQ(maybeSetValueResults.value().payloads, std::vector<SetValueResult>({result}));
+    }
+}
+
+TEST_F(ConnectedClientTest, testSetValuesGetResultCallback) {
+    std::vector<SetValueResult> results = {{
+                                                   .requestId = 0,
+                                                   .status = StatusCode::OK,
+                                           },
+                                           {
+                                                   .requestId = 1,
+                                                   .status = StatusCode::OK,
+                                           }};
+
+    SetValuesClient client(getCallbackClient());
+
+    (*(client.getResultCallback()))(results);
+
+    auto maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value());
+    ASSERT_EQ(maybeSetValueResults.value().payloads, results);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
new file mode 100644
index 0000000..62a7098
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DefaultVehicleHal.h"
+
+#include <IVehicleHardware.h>
+#include <LargeParcelableBase.h>
+#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <optional>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::IVehicle;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Result;
+
+using ::testing::Eq;
+using ::testing::WhenSortedBy;
+
+class MockVehicleHardware final : public IVehicleHardware {
+  public:
+    std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
+        return mPropertyConfigs;
+    }
+
+    StatusCode setValues(std::function<void(const std::vector<SetValueResult>&)>&&,
+                         const std::vector<SetValueRequest>&) override {
+        // TODO(b/200737967): mock this.
+        return StatusCode::OK;
+    }
+
+    StatusCode getValues(std::function<void(const std::vector<GetValueResult>&)>&&,
+                         const std::vector<GetValueRequest>&) const override {
+        // TODO(b/200737967): mock this.
+        return StatusCode::OK;
+    }
+
+    DumpResult dump(const std::vector<std::string>&) override {
+        // TODO(b/200737967): mock this.
+        return DumpResult{};
+    }
+
+    StatusCode checkHealth() override {
+        // TODO(b/200737967): mock this.
+        return StatusCode::OK;
+    }
+
+    void registerOnPropertyChangeEvent(
+            std::function<void(const std::vector<VehiclePropValue>&)>&&) override {
+        // TODO(b/200737967): mock this.
+    }
+
+    void registerOnPropertySetErrorEvent(
+            std::function<void(const std::vector<SetValueErrorEvent>&)>&&) override {
+        // TODO(b/200737967): mock this.
+    }
+
+    // Test functions.
+    void setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
+        mPropertyConfigs = configs;
+    }
+
+  private:
+    std::vector<VehiclePropConfig> mPropertyConfigs;
+};
+
+struct PropConfigCmp {
+    bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
+        return (a.prop < b.prop);
+    }
+} propConfigCmp;
+
+}  // namespace
+
+TEST(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
+    auto testConfigs = std::vector<VehiclePropConfig>({
+            VehiclePropConfig{
+                    .prop = 1,
+            },
+            VehiclePropConfig{
+                    .prop = 2,
+            },
+    });
+
+    auto hardware = std::make_unique<MockVehicleHardware>();
+    hardware->setPropertyConfigs(testConfigs);
+    auto vhal = ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+    std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+    VehiclePropConfigs output;
+    auto status = client->getAllPropConfigs(&output);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
+}
+
+TEST(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
+    std::vector<VehiclePropConfig> testConfigs;
+    // 10000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
+    for (size_t i = 0; i < 10000; i++) {
+        testConfigs.push_back(VehiclePropConfig{
+                .prop = static_cast<int32_t>(i),
+        });
+    }
+
+    auto hardware = std::make_unique<MockVehicleHardware>();
+    hardware->setPropertyConfigs(testConfigs);
+    auto vhal = ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+    std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+    VehiclePropConfigs output;
+    auto status = client->getAllPropConfigs(&output);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(output.payloads.empty());
+    Result<std::optional<std::vector<VehiclePropConfig>>> result =
+            LargeParcelableBase::stableLargeParcelableToParcelableVector<VehiclePropConfig>(
+                    output.sharedMemoryFd);
+    ASSERT_TRUE(result.ok());
+    ASSERT_TRUE(result.value().has_value());
+    ASSERT_EQ(result.value().value(), testConfigs);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
new file mode 100644
index 0000000..ca366cd
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MockVehicleCallback.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
+
+template <class T>
+std::optional<T> pop(std::list<T>& items) {
+    if (items.size() > 0) {
+        auto item = std::move(items.front());
+        items.pop_front();
+        return item;
+    }
+    return std::nullopt;
+}
+
+template <class T>
+static ScopedAStatus storeResults(const T& results, std::list<T>* storedResults) {
+    T resultsCopy{
+            .payloads = results.payloads,
+    };
+    int fd = results.sharedMemoryFd.get();
+    if (fd != -1) {
+        resultsCopy.sharedMemoryFd = ScopedFileDescriptor(dup(fd));
+    }
+    storedResults->push_back(std::move(resultsCopy));
+    return ScopedAStatus::ok();
+}
+
+}  // namespace
+
+ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return storeResults(results, &mGetValueResults);
+}
+
+ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return storeResults(results, &mSetValueResults);
+}
+
+ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues&, int32_t) {
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
+    return ScopedAStatus::ok();
+}
+
+std::optional<GetValueResults> MockVehicleCallback::nextGetValueResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mGetValueResults);
+}
+
+std::optional<SetValueResults> MockVehicleCallback::nextSetValueResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mSetValueResults);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
new file mode 100644
index 0000000..916575a
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
+#include <android-base/thread_annotations.h>
+
+#include <list>
+#include <mutex>
+#include <optional>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// MockVehicleCallback is a mock VehicleCallback implementation that simply stores the results.
+class MockVehicleCallback final
+    : public ::aidl::android::hardware::automotive::vehicle::BnVehicleCallback {
+  public:
+    ::ndk::ScopedAStatus onGetValues(
+            const ::aidl::android::hardware::automotive::vehicle::GetValueResults& results)
+            override;
+    ::ndk::ScopedAStatus onSetValues(
+            const ::aidl::android::hardware::automotive::vehicle::SetValueResults& results)
+            override;
+    ::ndk::ScopedAStatus onPropertyEvent(
+            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValues&,
+            int32_t) override;
+    ::ndk::ScopedAStatus onPropertySetError(
+            const ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors&) override;
+
+    // Test functions
+    std::optional<::aidl::android::hardware::automotive::vehicle::GetValueResults>
+    nextGetValueResults();
+    std::optional<::aidl::android::hardware::automotive::vehicle::SetValueResults>
+    nextSetValueResults();
+
+  private:
+    std::mutex mLock;
+    std::list<::aidl::android::hardware::automotive::vehicle::GetValueResults> mGetValueResults
+            GUARDED_BY(mLock);
+    std::list<::aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
+            GUARDED_BY(mLock);
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
diff --git a/bluetooth/a2dp/1.0/vts/OWNERS b/bluetooth/a2dp/1.0/vts/OWNERS
index 4e982a1..d3aab51 100644
--- a/bluetooth/a2dp/1.0/vts/OWNERS
+++ b/bluetooth/a2dp/1.0/vts/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 27441
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
diff --git a/bluetooth/audio/2.0/vts/OWNERS b/bluetooth/audio/2.0/vts/OWNERS
index b6c0813..b266b06 100644
--- a/bluetooth/audio/2.0/vts/OWNERS
+++ b/bluetooth/audio/2.0/vts/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+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
index b6c0813..b266b06 100644
--- a/bluetooth/audio/2.1/vts/OWNERS
+++ b/bluetooth/audio/2.1/vts/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp
index 6449c08..8d52ce9 100644
--- a/bluetooth/audio/2.2/Android.bp
+++ b/bluetooth/audio/2.2/Android.bp
@@ -14,6 +14,7 @@
     root: "android.hardware",
     srcs: [
         "types.hal",
+        "IBluetoothAudioPort.hal",
         "IBluetoothAudioProvider.hal",
         "IBluetoothAudioProvidersFactory.hal",
     ],
diff --git a/bluetooth/audio/2.2/IBluetoothAudioPort.hal b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
new file mode 100644
index 0000000..344899c
--- /dev/null
+++ b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio@2.2;
+
+import @2.0::IBluetoothAudioPort;
+import android.hardware.audio.common@5.0::SinkMetadata;
+
+interface IBluetoothAudioPort extends @2.0::IBluetoothAudioPort  {
+    /**
+     * Called when the metadata of the stream's sink has been changed.
+     *
+     * @param sinkMetadata Description of the audio that is recorded by the
+     *    clients.
+     */
+    updateSinkMetadata(SinkMetadata sinkMetadata);
+};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index ad8c839..bc16b01 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -17,7 +17,7 @@
 package android.hardware.bluetooth.audio@2.2;
 
 import @2.1::IBluetoothAudioProvider;
-import @2.0::IBluetoothAudioPort;
+import @2.2::IBluetoothAudioPort;
 import @2.0::Status;
 
 /**
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
index eeff4de..7fb5b6c 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
@@ -16,7 +16,10 @@
 
 package android.hardware.bluetooth.audio@2.2;
 
+import IBluetoothAudioProvider;
 import @2.1::IBluetoothAudioProvidersFactory;
+import @2.0::Status;
+import @2.1::SessionType;
 
 /**
  * This factory allows a HAL implementation to be split into multiple
@@ -30,4 +33,19 @@
  * for return value must be invoked synchronously before the API call returns.
  */
 interface IBluetoothAudioProvidersFactory extends @2.1::IBluetoothAudioProvidersFactory {
+    /**
+     * Opens an audio provider for a session type. To close the provider, it is
+     * necessary to release references to the returned provider object.
+     *
+     * @param sessionType The session type (e.g.
+     *    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+     *
+     * @return status One of the following
+     *    SUCCESS if the Audio HAL successfully opens the provider with the
+     *        given session type
+     *    FAILURE if the Audio HAL cannot open the provider
+     * @return provider The provider of the specified session type
+     */
+    openProvider_2_2(SessionType sessionType)
+        generates (Status status, IBluetoothAudioProvider provider);
 };
diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
index 126bc9e..2a6d93a 100644
--- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
@@ -54,7 +54,7 @@
 }
 
 Return<void> A2dpOffloadAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
index 0d918e1..ba31d39 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
@@ -70,7 +70,7 @@
 }
 
 Return<void> A2dpSoftwareAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
index 3d4f0cc..ac3aece 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
@@ -40,7 +40,7 @@
   bool isValid(const V2_1::SessionType& sessionType) override;
   bool isValid(const V2_0::SessionType& sessionType) override;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
new file mode 100644
index 0000000..c5613fb
--- /dev/null
+++ b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.2/types.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+using ::android::hardware::audio::common::V5_0::SourceMetadata;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
+class AudioPort_2_0_to_2_2_Wrapper : public V2_2::IBluetoothAudioPort {
+ public:
+  AudioPort_2_0_to_2_2_Wrapper(const sp<V2_0::IBluetoothAudioPort>& port) {
+    this->port = port;
+  }
+
+  Return<void> startStream() override { return port->startStream(); }
+  Return<void> suspendStream() override { return port->suspendStream(); }
+  Return<void> stopStream() override { return port->stopStream(); }
+  Return<void> getPresentationPosition(
+      getPresentationPosition_cb _hidl_cb) override {
+    return port->getPresentationPosition(_hidl_cb);
+  }
+  Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
+    return port->updateMetadata(sourceMetadata);
+  }
+  Return<void> updateSinkMetadata(const SinkMetadata&) override {
+    // DO NOTHING, 2.0 AudioPort doesn't support sink metadata updates
+    return Void();
+  }
+
+  sp<V2_0::IBluetoothAudioPort> port;
+};
+
+}  // namespace implementation
+}  // namespace V2_2
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 3655bc0..3c0ff42 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 
@@ -51,7 +52,7 @@
       audio_config_({}) {}
 
 Return<void> BluetoothAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   AudioConfiguration audioConfig_2_2;
 
@@ -67,11 +68,13 @@
     audioConfig_2_2.codecConfig(audioConfig.codecConfig());
   }
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> BluetoothAudioProvider::startSession_2_1(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   AudioConfiguration audioConfig_2_2;
   if (audioConfig.getDiscriminator() ==
@@ -92,11 +95,13 @@
     audioConfig_2_2.codecConfig(audioConfig.codecConfig());
   }
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> BluetoothAudioProvider::startSession_2_2(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   if (hostIf == nullptr) {
     _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index b7581ba..0f1f3c6 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -26,7 +26,7 @@
 namespace implementation {
 
 using ::android::sp;
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
 
 using BluetoothAudioStatus =
     ::android::hardware::bluetooth::audio::V2_0::Status;
@@ -41,13 +41,13 @@
   virtual bool isValid(const V2_1::SessionType& sessionType) = 0;
   virtual bool isValid(const V2_0::SessionType& sessionType) = 0;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
-  Return<void> startSession_2_1(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
-  Return<void> startSession_2_2(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
   Return<void> streamStarted(BluetoothAudioStatus status) override;
@@ -59,7 +59,7 @@
 
   V2_1::SessionType session_type_;
   AudioConfiguration audio_config_;
-  sp<V2_0::IBluetoothAudioPort> stack_iface_;
+  sp<V2_2::IBluetoothAudioPort> stack_iface_;
 
   virtual Return<void> onSessionReady(startSession_cb _hidl_cb) = 0;
 };
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 7438c80..510833d 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -122,6 +122,49 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvidersFactory::openProvider_2_2(
+    const V2_1::SessionType sessionType, openProvider_2_2_cb _hidl_cb) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
+  BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
+  BluetoothAudioProvider* provider = nullptr;
+
+  switch (sessionType) {
+    case V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+      provider = &a2dp_software_provider_instance_;
+      break;
+    case V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
+      provider = &a2dp_offload_provider_instance_;
+      break;
+    case V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+      provider = &hearing_aid_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+      provider = &leaudio_output_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      provider = &leaudio_offload_output_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
+      provider = &leaudio_input_provider_instance_;
+      break;
+    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+      provider = &leaudio_offload_input_provider_instance_;
+      break;
+    default:
+      status = BluetoothAudioStatus::FAILURE;
+  }
+
+  if (provider == nullptr || !provider->isValid(sessionType)) {
+    provider = nullptr;
+    status = BluetoothAudioStatus::FAILURE;
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
+               << ", status=" << toString(status);
+  }
+
+  _hidl_cb(status, provider);
+  return Void();
+}
+
 Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
     const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
   hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
index 8db330b..658249b 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
@@ -46,6 +46,9 @@
   Return<void> openProvider_2_1(const V2_1::SessionType sessionType,
                                 openProvider_2_1_cb _hidl_cb) override;
 
+  Return<void> openProvider_2_2(const V2_1::SessionType sessionType,
+                                openProvider_2_2_cb _hidl_cb) override;
+
   Return<void> getProviderCapabilities_2_1(
       const V2_1::SessionType sessionType,
       getProviderCapabilities_2_1_cb _hidl_cb) override;
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
index c79b910..9b3294f 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
@@ -66,7 +66,7 @@
 }
 
 Return<void> HearingAidAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
index 426c443..63290b5 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
@@ -40,7 +40,7 @@
   bool isValid(const V2_1::SessionType& sessionType) override;
   bool isValid(const V2_0::SessionType& sessionType) override;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
index af6ec99..9ec1776 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 
@@ -83,11 +84,13 @@
        .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
        .dataIntervalUs = 0});
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> LeAudioAudioProvider::startSession_2_2(
-    const sp<V2_0::IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
index 40c26e0..3de1724 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
@@ -45,7 +45,7 @@
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
-  Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
index 7b70654..e3da267 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 #include "BluetoothAudioSupportedCodecsDB_2_2.h"
@@ -91,11 +92,13 @@
       .peerDelay = 0,
       .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> LeAudioOffloadAudioProvider::startSession_2_2(
-    const sp<V2_0::IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
index 5620295..fe58de5 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
@@ -38,7 +38,7 @@
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
-  Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
new file mode 100644
index 0000000..60da877
--- /dev/null
+++ b/bluetooth/audio/aidl/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+aidl_interface {
+    name: "android.hardware.bluetooth.audio",
+    vendor_available: true,
+    srcs: ["android/hardware/bluetooth/audio/*.aidl"],
+    stability: "vintf",
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+        "android.hardware.audio.common",
+    ],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            enabled: false,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
index d7eecbb..ad44c26 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable AacCapabilities {
+  android.hardware.bluetooth.audio.AacObjectType objectType;
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  boolean variableBitRateSupported;
+  byte[] bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
index d7eecbb..6adef6d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable AacConfiguration {
+  android.hardware.bluetooth.audio.AacObjectType objectType;
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  boolean variableBitRateEnabled;
+  byte bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
similarity index 90%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
index 6eadbb7..c129c66 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -31,9 +31,11 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum AacObjectType {
+  MPEG2_LC = 1,
+  MPEG4_LC = 2,
+  MPEG4_LTP = 4,
+  MPEG4_SCALABLE = 8,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
index d7eecbb..4767b69 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable AptxCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte[] bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
index d7eecbb..91e88b3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable AptxConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
similarity index 82%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
index d7eecbb..20a7731 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union AudioCapabilities {
+  android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities;
+  android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities;
+  android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index d7eecbb..34f7837 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union AudioConfiguration {
+  android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
+  android.hardware.bluetooth.audio.CodecConfiguration codecConfig;
+  android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
similarity index 90%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
index 6eadbb7..319a5e2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -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;
+package android.hardware.bluetooth.audio;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum AudioLocation {
+  UNKNOWN = 1,
+  FRONT_LEFT = 2,
+  FRONT_RIGHT = 4,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
similarity index 79%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
index d7eecbb..b3aa709 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,14 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable BroadcastConfiguration {
+  android.hardware.bluetooth.audio.BroadcastConfiguration.BroadcastStreamMap[] streamMap;
+  @VintfStability
+  parcelable BroadcastStreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+    android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
index 6eadbb7..3ca93c3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum ChannelMode {
+  UNKNOWN = 1,
+  MONO = 2,
+  STEREO = 4,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
similarity index 73%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
index d7eecbb..b451880 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,16 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable CodecCapabilities {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.CodecCapabilities.Capabilities capabilities;
+  @VintfStability
+  union Capabilities {
+    android.hardware.bluetooth.audio.SbcCapabilities sbcCapabilities;
+    android.hardware.bluetooth.audio.AacCapabilities aacCapabilities;
+    android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities;
+    android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
similarity index 71%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
index 0c6c513..863aee2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,15 +31,19 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable CodecConfiguration {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  int encodedAudioBitrate;
+  int peerMtu;
+  boolean isScmstEnabled;
+  android.hardware.bluetooth.audio.CodecConfiguration.CodecSpecific config;
+  @VintfStability
+  union CodecSpecific {
+    android.hardware.bluetooth.audio.SbcConfiguration sbcConfig;
+    android.hardware.bluetooth.audio.AacConfiguration aacConfig;
+    android.hardware.bluetooth.audio.LdacConfiguration ldacConfig;
+    android.hardware.bluetooth.audio.AptxConfiguration aptxConfig;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index 6eadbb7..44b434b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,14 @@
 // 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;
+package android.hardware.bluetooth.audio;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum CodecType {
+  UNKNOWN = 0,
+  SBC = 1,
+  AAC = 2,
+  APTX = 3,
+  APTX_HD = 4,
+  LDAC = 5,
+  LC3 = 6,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
similarity index 81%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index d7eecbb..e389ef3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBluetoothAudioPort {
+  android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
+  void startStream();
+  void stopStream();
+  void suspendStream();
+  void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
similarity index 77%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index d7eecbb..84bcc0c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBluetoothAudioProvider {
+  void endSession();
+  android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.UnsynchronizedWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+  void streamStarted(in boolean status);
+  void streamSuspended(in boolean status);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
similarity index 79%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index d7eecbb..5e33deb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBluetoothAudioProviderFactory {
+  android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
+  android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
similarity index 86%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
index d7eecbb..3c650da 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Lc3Capabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
similarity index 86%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
index 6eadbb7..ef77da7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,12 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable Lc3Configuration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
index d7eecbb..19e041a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable LdacCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  byte[] bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 6eadbb7..a9d6c5e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,11 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacChannelMode {
+  UNKNOWN = 1,
+  STEREO = 2,
+  DUAL = 4,
+  MONO = 8,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
index d7eecbb..8a37638 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable LdacConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  byte bitsPerSample;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
similarity index 86%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index 6eadbb7..bc0d97b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,11 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacQualityIndex {
+  QUALITY_HIGH = 1,
+  QUALITY_MID = 2,
+  QUALITY_LOW = 4,
+  QUALITY_ABR = 8,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
similarity index 68%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
index d7eecbb..9efafca 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,21 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable LeAudioCapabilities {
+  android.hardware.bluetooth.audio.LeAudioMode mode;
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+  int supportedChannelCount;
+  android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union LeaudioCodecCapabilities {
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
similarity index 81%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index d7eecbb..bb3d7e4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,13 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union LeAudioCodecConfiguration {
+  android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+  @VintfStability
+  parcelable VendorConfiguration {
+    ParcelableHolder extension;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index d7eecbb..c6cb5cb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,15 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable LeAudioConfiguration {
+  android.hardware.bluetooth.audio.LeAudioMode mode;
+  android.hardware.bluetooth.audio.LeAudioConfiguration.LeAuioModeConfig modeConfig;
+  android.hardware.bluetooth.audio.CodecType codecType;
+  @VintfStability
+  union LeAuioModeConfig {
+    android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig;
+    android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
index 6eadbb7..766f637 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LeAudioMode {
+  UNKNOWN = 0,
+  UNICAST = 1,
+  BROADCAST = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
similarity index 86%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index d7eecbb..0c2f87d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable PcmCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+  byte[] bitsPerSample;
+  int[] dataIntervalUs;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
similarity index 86%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
index d7eecbb..93d7805 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable PcmConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
+  int dataIntervalUs;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
similarity index 83%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
index 0c6c513..810a9a1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -31,15 +31,15 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable PresentationPosition {
+  long remoteDeviceAudioDelayNanos;
+  long transmittedOctets;
+  android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimeStamp;
+  @VintfStability
+  parcelable TimeSpec {
+    long tvSec;
+    long tvNSec;
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
similarity index 89%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 9bfb725..5170f16 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapApduType {
-  APDU = 0,
-  APDU7816 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcAllocMethod {
+  ALLOC_MD_S = 1,
+  ALLOC_MD_L = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
similarity index 81%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
index d7eecbb..ec3aa0f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,15 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable SbcCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  byte[] blockLength;
+  byte[] numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  byte[] bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 6eadbb7..88fca4a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,12 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcChannelMode {
+  UNKNOWN = 1,
+  JOINT_STEREO = 2,
+  STEREO = 4,
+  DUAL = 8,
+  MONO = 16,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
similarity index 81%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
index d7eecbb..8eab9c3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,15 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable SbcConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  byte blockLength;
+  byte numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  byte bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
similarity index 77%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 0c6c513..900ab31 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,15 +31,15 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SessionType {
+  UNKNOWN = 0,
+  A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
+  A2DP_HARDWARE_OFFLOAD_DATAPATH = 2,
+  HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
+  LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
+  LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
+  LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
+  LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
similarity index 79%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
index d7eecbb..b385763 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,15 @@
 // 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.voice;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable UnicastConfiguration {
+  android.hardware.bluetooth.audio.UnicastConfiguration.UnicastStreamMap[] streamMap;
+  int peerDelay;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  @VintfStability
+  parcelable UnicastStreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+  }
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..4303883
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec capabilities
+ */
+@VintfStability
+parcelable AacCapabilities {
+    /* bitfield */
+    AacObjectType objectType;
+    int[] sampleRateHz;
+    /* bitfield */
+    ChannelMode channelMode;
+    boolean variableBitRateSupported;
+    byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..30338e7
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec configuration
+ */
+@VintfStability
+parcelable AacConfiguration {
+    AacObjectType objectType;
+    int sampleRateHz;
+    ChannelMode channelMode;
+    boolean variableBitRateEnabled;
+    byte bitsPerSample;
+}
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
similarity index 61%
copy from radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
index 540014a..480e422 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -14,16 +14,25 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.network;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-parcelable CellIdentityOperatorNames {
+@Backing(type="byte")
+enum AacObjectType {
     /**
-     * Long alpha operator name string or enhanced operator name string.
+     * MPEG-2 Low Complexity. Support is Mandatory.
      */
-    String alphaLong;
+    MPEG2_LC = 1,
     /**
-     * Short alpha operator name string or enhanced operator name string.
+     * MPEG-4 Low Complexity. Support is Optional.
      */
-    String alphaShort;
+    MPEG4_LC = 1 << 1,
+    /**
+     * MPEG-4 Long Term Prediction. Support is Optional.
+     */
+    MPEG4_LTP = 1 << 2,
+    /**
+     * MPEG-4 Scalable. Support is Optional.
+     */
+    MPEG4_SCALABLE = 1 << 3,
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
similarity index 62%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
index 46a9b1a..6a37fc6 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.bluetooth.audio;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+import android.hardware.bluetooth.audio.ChannelMode;
 
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec capabilities
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
-    /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
-     */
-    CdmaInformationRecord[] infoRec;
+parcelable AptxCapabilities {
+    int[] sampleRateHz;
+    /* bitfield */
+    ChannelMode channelMode;
+    byte[] bitsPerSample;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
similarity index 63%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
index 46a9b1a..83b7b0c 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.bluetooth.audio;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+import android.hardware.bluetooth.audio.ChannelMode;
 
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec configuration
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
-    /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
-     */
-    CdmaInformationRecord[] infoRec;
+parcelable AptxConfiguration {
+    int sampleRateHz;
+    ChannelMode channelMode;
+    byte bitsPerSample;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..6ed4472
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecCapabilities;
+import android.hardware.bluetooth.audio.LeAudioCapabilities;
+import android.hardware.bluetooth.audio.PcmCapabilities;
+
+/**
+ * Used to specify the capabilities of the different session types
+ */
+@VintfStability
+union AudioCapabilities {
+    PcmCapabilities pcmCapabilities;
+    CodecCapabilities codecCapabilities;
+    LeAudioCapabilities leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..ce515b5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.LeAudioConfiguration;
+import android.hardware.bluetooth.audio.PcmConfiguration;
+
+/**
+ * Used to configure either a Hardware or Software Encoding session based on session type
+ */
+@VintfStability
+union AudioConfiguration {
+    PcmConfiguration pcmConfig;
+    CodecConfiguration codecConfig;
+    LeAudioConfiguration leAudioConfig;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
similarity index 76%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
index 7f385de..dedfbf9 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
 @Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+enum AudioLocation {
+    UNKNOWN = 1,
+    FRONT_LEFT = 1 << 1,
+    FRONT_RIGHT = 1 << 2,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
new file mode 100644
index 0000000..07d05f1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable BroadcastConfiguration {
+    @VintfStability
+    parcelable BroadcastStreamMap {
+        /*
+         * The connection handle used for a unicast or a broadcast group.
+         * Range: 0x0000 to 0xEFFF
+         */
+        char streamHandle;
+        /*
+         * Audio channel allocation is  a bit field, each enabled bit means that given audio
+         * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+         * least significant bit to the most significant bit.
+         */
+        int audioChannelAllocation;
+        LeAudioCodecConfiguration leAudioCondecConfig;
+    }
+    BroadcastStreamMap[] streamMap;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
similarity index 74%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
index 7f385de..2df879d 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+@Backing(type="byte")
+enum ChannelMode {
+    UNKNOWN = 1,
+    MONO = 1 << 1,
+    STEREO = 1 << 2,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..0eee8cb
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacCapabilities;
+import android.hardware.bluetooth.audio.AptxCapabilities;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LdacCapabilities;
+import android.hardware.bluetooth.audio.SbcCapabilities;
+
+/**
+ * Used to specify the capabilities of the codecs supported by Hardware Encoding.
+ * AptX and AptX-HD both use the AptxCapabilities field.
+ */
+@VintfStability
+parcelable CodecCapabilities {
+    @VintfStability
+    union Capabilities {
+        SbcCapabilities sbcCapabilities;
+        AacCapabilities aacCapabilities;
+        LdacCapabilities ldacCapabilities;
+        AptxCapabilities aptxCapabilities;
+    }
+    CodecType codecType;
+    Capabilities capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..fac90f0
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacConfiguration;
+import android.hardware.bluetooth.audio.AptxConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LdacConfiguration;
+import android.hardware.bluetooth.audio.SbcConfiguration;
+
+/**
+ * Used to configure a Hardware Encoding session.
+ * AptX and AptX-HD both use the AptxConfiguration field.
+ */
+@VintfStability
+parcelable CodecConfiguration {
+    @VintfStability
+    union CodecSpecific {
+        SbcConfiguration sbcConfig;
+        AacConfiguration aacConfig;
+        LdacConfiguration ldacConfig;
+        AptxConfiguration aptxConfig;
+    }
+    CodecType codecType;
+    /**
+     * The encoded audio bitrate in bits / second.
+     * 0x00000000 - The audio bitrate is not specified / unused
+     * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second
+     * 0x01000000 - 0xFFFFFFFF - Reserved
+     *
+     * The HAL needs to support all legal bitrates for the selected codec.
+     */
+    int encodedAudioBitrate;
+    /**
+     * Peer MTU (in two-octets)
+     */
+    int peerMtu;
+    /**
+     * Content protection by SCMS-T
+     */
+    boolean isScmstEnabled;
+    CodecSpecific config;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
similarity index 76%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
index 7f385de..68c60f5 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
 @Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+enum CodecType {
+    UNKNOWN,
+    SBC,
+    AAC,
+    APTX,
+    APTX_HD,
+    LDAC,
+    LC3,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..50e3197
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.audio.common.SourceMetadata;
+import android.hardware.bluetooth.audio.PresentationPosition;
+
+/**
+ * HAL interface from the Audio HAL to the Bluetooth stack
+ *
+ * The Audio HAL calls methods in this interface to start, suspend, and stop
+ * an audio stream. These calls return immediately and the results, if any,
+ * are sent over the IBluetoothAudioProvider interface.
+ *
+ * Moreover, the Audio HAL can also get the presentation position of the stream
+ * and provide stream metadata.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioPort {
+    /**
+     * Get the audio presentation position.
+     *
+     * @return the audio presentation position
+     *
+     */
+    PresentationPosition getPresentationPosition();
+
+    /**
+     * This indicates that the caller of this method has opened the data path
+     * and wants to start an audio stream. The caller must wait for a
+     * IBluetoothAudioProvider.streamStarted(Status) call.
+     */
+    void startStream();
+
+    /**
+     * This indicates that the caller of this method wants to stop the audio
+     * stream. The data path will be closed after this call. There is no
+     * callback from the IBluetoothAudioProvider interface even though the
+     * teardown is asynchronous.
+     */
+    void stopStream();
+
+    /**
+     * This indicates that the caller of this method wants to suspend the audio
+     * stream. The caller must wait for the Bluetooth process to call
+     * IBluetoothAudioProvider.streamSuspended(Status). The caller still keeps
+     * the data path open.
+     */
+    void suspendStream();
+
+    /**
+     * Called when the metadata of the stream's source has been changed.
+     *
+     * @param sourceMetadata Description of the audio that is played by the
+     *    clients.
+     */
+    void updateMetadata(in SourceMetadata sourceMetadata);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..cebd808
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.IBluetoothAudioPort;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.UnsynchronizedWrite;
+
+/**
+ * HAL interface from the Bluetooth stack to the Audio HAL
+ *
+ * The Bluetooth stack calls methods in this interface to start and end audio
+ * sessions and sends callback events to the Audio HAL.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioProvider {
+    /**
+     * Ends the current session and unregisters the IBluetoothAudioPort
+     * interface.
+     */
+    void endSession();
+
+    /**
+     * This method indicates that the Bluetooth stack is ready to stream audio.
+     * It registers an instance of IBluetoothAudioPort with and provides the
+     * current negotiated codec to the Audio HAL. After this method is called,
+     * the Audio HAL can invoke IBluetoothAudioPort.startStream().
+     *
+     * Note: endSession() must be called to unregister this IBluetoothAudioPort
+     *
+     * @param hostIf An instance of IBluetoothAudioPort for stream control
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     *
+     * @return The fast message queue for audio data from/to this
+     *    provider. Audio data will be in PCM format as specified by the
+     *    audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
+     *    from/to hardware or on failure
+     */
+    MQDescriptor<int, UnsynchronizedWrite> startSession(
+            in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig);
+
+    /**
+     * Callback for IBluetoothAudioPort.startStream()
+     *
+     * @param status true for SUCCESS or false for FAILURE
+     */
+    void streamStarted(in boolean status);
+
+    /**
+     * Callback for IBluetoothAudioPort.suspendStream()
+     *
+     * @param status true for SUCCESS or false for FAILURE
+     */
+    void streamSuspended(in boolean status);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..3cde22c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
+import android.hardware.bluetooth.audio.SessionType;
+/**
+ * This factory allows a HAL implementation to be split into multiple
+ * independent providers.
+ *
+ * When the Bluetooth stack is ready to create an audio session, it must first
+ * obtain the IBluetoothAudioProvider for that session type by calling
+ * openProvider().
+ *
+ */
+
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+    /**
+     * Gets a list of audio capabilities for a session type.
+     *
+     * For software encoding, the PCM capabilities are returned.
+     * For hardware encoding, the supported codecs and their capabilities are
+     * returned.
+     *
+     * @param sessionType The session type (e.g.
+     *    A2DP_SOFTWARE_ENCODING_DATAPATH).
+     * @return A list containing all the capabilities
+     *    supported by the sesson type. The capabilities is a list of
+     *    available options when configuring the codec for the session.
+     *    For software encoding it is the PCM data rate.
+     *    For hardware encoding it is the list of supported codecs and their
+     *    capabilities.
+     *    If a provider isn't supported, an empty list should be returned.
+     *    Note: Only one entry should exist per codec when using hardware
+     *    encoding.
+     */
+    AudioCapabilities[] getProviderCapabilities(in SessionType sessionType);
+
+    /**
+     * Opens an audio provider for a session type. To close the provider, it is
+     * necessary to release references to the returned provider object.
+     *
+     * @param sessionType The session type (e.g.
+     *    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+     *
+     * @return provider The provider of the specified session type
+     */
+    IBluetoothAudioProvider openProvider(in SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..1aedefd
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec capabilities.
+ */
+@VintfStability
+parcelable Lc3Capabilities {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte[] pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int[] samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int[] frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int[] octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..77c04c1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec configuration.
+ */
+@VintfStability
+parcelable Lc3Configuration {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..44cca7e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec capabilities
+ * all qualities must be supported.
+ */
+@VintfStability
+parcelable LdacCapabilities {
+    int[] sampleRateHz;
+    /* bitfiled */
+    LdacChannelMode channelMode;
+    /* bitfiled */
+    LdacQualityIndex qualityIndex;
+    byte[] bitsPerSample;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
similarity index 69%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 7f385de..3acca32 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
+/**
+ * Channel Mode: 3 bits
+ */
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+@Backing(type="byte")
+enum LdacChannelMode {
+    UNKNOWN = 1,
+    STEREO = 1 << 1,
+    DUAL = 1 << 2,
+    MONO = 1 << 3,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..cc03dd0
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec configuration
+ * Only used when configuring the codec.
+ */
+@VintfStability
+parcelable LdacConfiguration {
+    int sampleRateHz;
+    LdacChannelMode channelMode;
+    LdacQualityIndex qualityIndex;
+    byte bitsPerSample;
+}
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
similarity index 63%
rename from radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
rename to bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index 540014a..fc532f4 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,16 +14,25 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.network;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-parcelable CellIdentityOperatorNames {
+@Backing(type="byte")
+enum LdacQualityIndex {
     /**
-     * Long alpha operator name string or enhanced operator name string.
+     * 990kbps
      */
-    String alphaLong;
+    QUALITY_HIGH = 1,
     /**
-     * Short alpha operator name string or enhanced operator name string.
+     * 660kbps
      */
-    String alphaShort;
+    QUALITY_MID = 1 << 1,
+    /**
+     * 330kbps
+     */
+    QUALITY_LOW = 1 << 2,
+    /**
+     * Adaptive Bit Rate mode
+     */
+    QUALITY_ABR = 1 << 3,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
new file mode 100644
index 0000000..ea05820
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioLocation;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.LeAudioMode;
+
+/**
+ * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding.
+ */
+@VintfStability
+parcelable LeAudioCapabilities {
+    @VintfStability
+    parcelable VendorCapabilities {
+        ParcelableHolder extension;
+    }
+    @VintfStability
+    union LeaudioCodecCapabilities {
+        Lc3Capabilities lc3Capabilities;
+        VendorCapabilities vendorCapabillities;
+    }
+    LeAudioMode mode;
+    CodecType codecType;
+    /*
+     * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time.
+     * Example: 0x27 = 0b00100111: One, two, three or six channels supported.
+     */
+    AudioLocation supportedChannel;
+    int supportedChannelCount;
+    LeaudioCodecCapabilities leaudioCodecCapabilities;
+}
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
similarity index 61%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index 46a9b1a..421eeb2 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.bluetooth.audio;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+import android.hardware.bluetooth.audio.Lc3Configuration;
 
 @VintfStability
-parcelable CdmaInformationRecords {
-    /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
-     */
-    CdmaInformationRecord[] infoRec;
+union LeAudioCodecConfiguration {
+    @VintfStability
+    parcelable VendorConfiguration {
+        ParcelableHolder extension;
+    }
+    Lc3Configuration lc3Config;
+    VendorConfiguration vendorConfig;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..a212c96
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.BroadcastConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LeAudioMode;
+import android.hardware.bluetooth.audio.UnicastConfiguration;
+
+@VintfStability
+parcelable LeAudioConfiguration {
+    @VintfStability
+    union LeAuioModeConfig {
+        UnicastConfiguration unicastConfig;
+        BroadcastConfiguration broadcastConfig;
+    }
+    /*
+     * The mode of the LE audio
+     */
+    LeAudioMode mode;
+    LeAuioModeConfig modeConfig;
+    CodecType codecType;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
similarity index 76%
rename from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
rename to bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
index 7f385de..2cf019e 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+@Backing(type="byte")
+enum LeAudioMode {
+    UNKNOWN,
+    UNICAST,
+    BROADCAST,
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
similarity index 60%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index 46a9b1a..776b777 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.bluetooth.audio;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+import android.hardware.bluetooth.audio.ChannelMode;
 
+/**
+ * Used for Software Encoding audio feed capabilities
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
+parcelable PcmCapabilities {
+    int[] sampleRateHz;
+    ChannelMode[] channelMode;
+    byte[] bitsPerSample;
     /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
+     * Data interval for data transfer
      */
-    CdmaInformationRecord[] infoRec;
+    int[] dataIntervalUs;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
similarity index 61%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
index 46a9b1a..03aa27b 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.bluetooth.audio;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+import android.hardware.bluetooth.audio.ChannelMode;
 
+/**
+ * Used for Software Encoding audio feed configuration
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
+parcelable PcmConfiguration {
+    int sampleRateHz;
+    ChannelMode channelMode;
+    byte bitsPerSample;
     /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
+     * Data interval for data transfer
      */
-    CdmaInformationRecord[] infoRec;
+    int dataIntervalUs;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..17e746f
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+parcelable PresentationPosition {
+    @VintfStability
+    parcelable TimeSpec {
+        /**
+         * seconds
+         */
+        long tvSec;
+        /**
+         *  nanoseconds
+         */
+        long tvNSec;
+    }
+    /*
+     * remoteDeviceAudioDelayNanos the audio delay from when the remote
+     * device (e.g. headset) receives audio data to when the device plays the
+     * sound. If the delay is unknown, the value is set to zero.
+     */
+    long remoteDeviceAudioDelayNanos;
+    /*
+     * transmittedOctets the number of audio data octets that were sent
+     * to a remote device. This excludes octets that have been written to the
+     * data path but have not been sent to the remote device. The count is
+     * not reset until stopStream() is called. If the software data path is
+     * unused (e.g. Hardware Offload), the value is set to 0.
+     */
+    long transmittedOctets;
+    /*
+     * transmittedOctetsTimeStamp the value of CLOCK_MONOTONIC
+     * corresponding to transmittedOctets. If the software data path is
+     * unused (e.g., for Hardware Offload), the value is set to zero.
+     */
+    TimeSpec transmittedOctetsTimeStamp;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
similarity index 70%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 7f385de..7047e34 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+@Backing(type="byte")
+enum SbcAllocMethod {
+    /**
+     * SNR
+     */
+    ALLOC_MD_S = 1,
+    /**
+     * Loudness
+     */
+    ALLOC_MD_L = 1 << 1,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..cf62ed4
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec capabilities.
+ */
+@VintfStability
+parcelable SbcCapabilities {
+    int[] sampleRateHz;
+    /* bitfield */
+    SbcChannelMode channelMode;
+    byte[] blockLength;
+    byte[] numSubbands;
+    /* bitfield */
+    SbcAllocMethod allocMethod;
+    byte[] bitsPerSample;
+    /*
+     * range from 2 to 250.
+     */
+    int minBitpool;
+    /*
+     * range from 2 to 250.
+     */
+    int maxBitpool;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
similarity index 70%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 7f385de..7eb38cd 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+@Backing(type="byte")
+enum SbcChannelMode {
+    UNKNOWN = 1,
+    JOINT_STEREO = 1 << 1,
+    STEREO = 1 << 2,
+    DUAL = 1 << 3,
+    MONO = 1 << 4,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..054d03e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec configuration.
+ */
+@VintfStability
+parcelable SbcConfiguration {
+    int sampleRateHz;
+    SbcChannelMode channelMode;
+    byte blockLength;
+    byte numSubbands;
+    SbcAllocMethod allocMethod;
+    byte bitsPerSample;
+    /*
+     * range from 2 to 250.
+     */
+    int minBitpool;
+    /*
+     * range from 2 to 250.
+     */
+    int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..b588869
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SessionType {
+    UNKNOWN,
+    /**
+     * A2DP legacy that AVDTP media is encoded by Bluetooth Stack
+     */
+    A2DP_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * The encoding of AVDTP media is done by HW and there is control only
+     */
+    A2DP_HARDWARE_OFFLOAD_DATAPATH,
+    /**
+     * Used when encoded by Bluetooth Stack and streaming to Hearing Aid
+     */
+    HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * Used when encoded by Bluetooth Stack and streaming to LE Audio device
+     */
+    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * Used when decoded by Bluetooth Stack and streaming to audio framework
+     */
+    LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+    /**
+     * Encoding is done by HW an there is control only
+     */
+    LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+    /**
+     * Decoding is done by HW an there is control only
+     */
+    LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
new file mode 100644
index 0000000..7be2c5b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable UnicastConfiguration {
+    @VintfStability
+    parcelable UnicastStreamMap {
+        /*
+         * The connection handle used for a unicast or a broadcast group.
+         * Range: 0x0000 to 0xEFFF
+         */
+        char streamHandle;
+        /*
+         * Audio channel allocation is  a bit field, each enabled bit means that given audio
+         * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+         * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
+         * Audio Location assigned number.
+         */
+        int audioChannelAllocation;
+    }
+    UnicastStreamMap[] streamMap;
+    int peerDelay;
+    LeAudioCodecConfiguration leAudioCodecConfig;
+}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 19d2d92..4f712bf 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -22,6 +22,7 @@
     export_include_dirs: ["session/"],
     header_libs: ["libhardware_headers"],
     shared_libs: [
+        "android.hardware.audio.common@5.0",
         "android.hardware.bluetooth.audio@2.0",
         "android.hardware.bluetooth.audio@2.1",
         "android.hardware.bluetooth.audio@2.2",
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
index a35dde2..ed92847 100644
--- a/bluetooth/audio/utils/OWNERS
+++ b/bluetooth/audio/utils/OWNERS
@@ -1,3 +1,3 @@
-include platform/system/bt:/OWNERS
+include platform/packages/modules/Bluetooth:/OWNERS
 
 cheneyni@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
new file mode 100644
index 0000000..b4ba8cf
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession_2_2.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionControl_2_2 {
+  using SessionType_2_1 =
+      ::android::hardware::bluetooth::audio::V2_1::SessionType;
+  using AudioConfiguration_2_2 =
+      ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
+
+ public:
+  // The control API helps to check if session is ready or not
+  // @return: true if the Bluetooth stack has started th specified session
+  static bool IsSessionReady(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->IsSessionReady();
+    }
+    return false;
+  }
+
+  // The control API helps the bluetooth_audio module to register
+  // PortStatusCallbacks
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+    }
+    return kObserversCookieUndefined;
+  }
+
+  // The control API helps the bluetooth_audio module to unregister
+  // PortStatusCallbacks
+  // @param: cookie - indicates which bluetooth_audio output is
+  static void UnregisterControlResultCback(const SessionType_2_1& session_type,
+                                           uint16_t cookie) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+    }
+  }
+
+  // The control API for the bluetooth_audio module to get current
+  // AudioConfiguration
+  static const AudioConfiguration_2_2 GetAudioConfig(
+      const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioConfig();
+    } else if (session_type ==
+               SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+      return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
+    } else {
+      return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
+    }
+  }
+
+  // Those control APIs for the bluetooth_audio module to start / suspend / stop
+  // stream, to check position, and to update metadata.
+  static bool StartStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->StartStream();
+    }
+    return false;
+  }
+
+  static bool SuspendStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->SuspendStream();
+    }
+    return false;
+  }
+
+  static void StopStream(const SessionType_2_1& session_type) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->StopStream();
+    }
+  }
+
+  static bool GetPresentationPosition(const SessionType_2_1& session_type,
+                                      uint64_t* remote_delay_report_ns,
+                                      uint64_t* total_bytes_readed,
+                                      timespec* data_position) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->GetPresentationPosition(
+          remote_delay_report_ns, total_bytes_readed, data_position);
+    }
+    return false;
+  }
+
+  static void UpdateTracksMetadata(
+      const SessionType_2_1& session_type,
+      const struct source_metadata* source_metadata) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->GetAudioSession()->UpdateTracksMetadata(source_metadata);
+    }
+  }
+
+  static void UpdateSinkMetadata(const SessionType_2_1& session_type,
+                                 const struct sink_metadata* sink_metadata) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->UpdateSinkMetadata(sink_metadata);
+    }
+  }
+
+  // The control API writes stream to FMQ
+  static size_t OutWritePcmData(const SessionType_2_1& session_type,
+                                const void* buffer, size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes);
+    }
+    return 0;
+  }
+
+  // The control API reads stream from FMQ
+  static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
+                              size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
+    }
+    return 0;
+  }
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 9d9ea41..80df5d9 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -20,20 +20,32 @@
 
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
+#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
 
 namespace android {
 namespace bluetooth {
 namespace audio {
+
+using ::android::hardware::audio::common::V5_0::AudioSource;
+using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
 using SessionType_2_0 =
     ::android::hardware::bluetooth::audio::V2_0::SessionType;
 
+using AudioConfiguration_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
+
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
 
+using IBluetoothAudioPort_2_2 =
+    ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
 namespace {
 bool is_2_0_session_type(
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -52,7 +64,9 @@
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
         session_type)
     : audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
-          static_cast<SessionType_2_0>(session_type))) {
+          static_cast<SessionType_2_0>(session_type))),
+      audio_session_2_1(
+          BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type)) {
   if (is_2_0_session_type(session_type)) {
     session_type_2_1_ = (SessionType_2_1::UNKNOWN);
   } else {
@@ -74,6 +88,58 @@
 BluetoothAudioSession_2_2::GetAudioSession() {
   return audio_session;
 }
+std::shared_ptr<BluetoothAudioSession_2_1>
+BluetoothAudioSession_2_2::GetAudioSession_2_1() {
+  return audio_session_2_1;
+}
+
+void BluetoothAudioSession_2_2::UpdateSinkMetadata(
+    const struct sink_metadata* sink_metadata) {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+               << " has NO session";
+    return;
+  }
+
+  ssize_t track_count = sink_metadata->track_count;
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+            << ", " << track_count << " track(s)";
+  if (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+      session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+    return;
+  }
+
+  struct record_track_metadata* track = sink_metadata->tracks;
+  SinkMetadata sinkMetadata;
+  RecordTrackMetadata* halMetadata;
+
+  sinkMetadata.tracks.resize(track_count);
+  halMetadata = sinkMetadata.tracks.data();
+  while (track_count && track) {
+    halMetadata->source = static_cast<AudioSource>(track->source);
+    halMetadata->gain = track->gain;
+    // halMetadata->destination leave unspecified
+    LOG(INFO) << __func__
+              << " - SessionType=" << toString(GetAudioSession()->session_type_)
+              << ", source=" << track->source
+              << ", dest_device=" << track->dest_device
+              << ", gain=" << track->gain
+              << ", dest_device_address=" << track->dest_device_address;
+    --track_count;
+    ++track;
+    ++halMetadata;
+  }
+
+  /* This is called just for 2.2 sessions, so it's safe to do this casting*/
+  IBluetoothAudioPort_2_2* stack_iface_2_2_ =
+      static_cast<IBluetoothAudioPort_2_2*>(audio_session->stack_iface_.get());
+  auto hal_retval = stack_iface_2_2_->updateSinkMetadata(sinkMetadata);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_2_1_) << " failed";
+  }
+}
 
 // The control function is for the bluetooth_audio module to get the current
 // AudioConfiguration
@@ -82,7 +148,19 @@
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (IsSessionReady()) {
     // If session is unknown it means it should be 2.0 type
-    if (session_type_2_1_ != SessionType_2_1::UNKNOWN) return audio_config_2_2_;
+    if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
+      if (audio_config_2_2_ != invalidSoftwareAudioConfiguration)
+        return audio_config_2_2_;
+
+      ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
+      const AudioConfiguration_2_1 fromConf =
+          GetAudioSession_2_1()->GetAudioConfig();
+      if (fromConf.getDiscriminator() ==
+          AudioConfiguration_2_1::hidl_discriminator::pcmConfig) {
+        toConf.pcmConfig() = fromConf.pcmConfig();
+        return toConf;
+      }
+    }
 
     ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
     const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index d3d0bd3..d6ae3d7 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -22,6 +22,7 @@
 #include <unordered_map>
 
 #include "BluetoothAudioSession.h"
+#include "BluetoothAudioSession_2_1.h"
 
 namespace android {
 namespace bluetooth {
@@ -30,6 +31,7 @@
 class BluetoothAudioSession_2_2 {
  private:
   std::shared_ptr<BluetoothAudioSession> audio_session;
+  std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1;
 
   ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
 
@@ -56,6 +58,7 @@
   bool IsSessionReady();
 
   std::shared_ptr<BluetoothAudioSession> GetAudioSession();
+  std::shared_ptr<BluetoothAudioSession_2_1> GetAudioSession_2_1();
 
   // The report function is used to report that the Bluetooth stack has started
   // this session without any failure, and will invoke session_changed_cb_ to
@@ -71,6 +74,8 @@
   const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
   GetAudioConfig();
 
+  void UpdateSinkMetadata(const struct sink_metadata* sink_metadata);
+
   static constexpr ::android::hardware::bluetooth::audio::V2_2::
       AudioConfiguration& kInvalidSoftwareAudioConfiguration =
           invalidSoftwareAudioConfiguration;
diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp
new file mode 100644
index 0000000..2a1f215
--- /dev/null
+++ b/camera/device/3.8/Android.bp
@@ -0,0 +1,38 @@
+// 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.camera.device@3.8",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "ICameraDevice.hal",
+        "ICameraDeviceCallback.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.device@3.6",
+        "android.hardware.camera.device@3.7",
+        "android.hardware.camera.metadata@3.2",
+        "android.hardware.camera.metadata@3.3",
+        "android.hardware.camera.metadata@3.4",
+        "android.hardware.camera.metadata@3.5",
+        "android.hardware.camera.metadata@3.6",
+        "android.hardware.graphics.common@1.0",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: false,
+}
diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal
new file mode 100644
index 0000000..448f176
--- /dev/null
+++ b/camera/device/3.8/ICameraDevice.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera.device@3.8;
+
+import @3.7::ICameraDevice;
+
+/**
+ * Camera device interface
+ *
+ * Supports the android.hardware.Camera API, and the android.hardware.camera2
+ * API at LIMITED or better hardware level.
+ *
+ * ICameraDevice.open() must return @3.2::ICameraDeviceSession,
+ * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or
+ * @3.7::ICameraDeviceSession.
+ */
+interface ICameraDevice extends @3.7::ICameraDevice {
+};
diff --git a/camera/device/3.8/ICameraDeviceCallback.hal b/camera/device/3.8/ICameraDeviceCallback.hal
new file mode 100644
index 0000000..de0775d
--- /dev/null
+++ b/camera/device/3.8/ICameraDeviceCallback.hal
@@ -0,0 +1,34 @@
+/*
+ * 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.camera.device@3.8;
+
+import @3.5::ICameraDeviceCallback;
+
+/**
+ * Callback methods for the HAL to call into the framework.
+ */
+interface ICameraDeviceCallback extends @3.5::ICameraDeviceCallback {
+    /**
+     * Identical to @3.5::ICameraDeviceCallback.notify, except that it takes a
+     * list of @3.8::NotifyMsg which contain readout timestamp in addition
+     * to exposure start timestamp for shutter.
+     *
+     * The readout timestamp is used for the framework to re-time the viewfinder
+     * frames targeted for SurfaceView so that preview jitter can be reduced.
+     */
+    notify_3_8(vec<NotifyMsg> msgs);
+};
diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal
new file mode 100644
index 0000000..843d050
--- /dev/null
+++ b/camera/device/3.8/types.hal
@@ -0,0 +1,69 @@
+/*
+ * 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.camera.device@3.8;
+
+import @3.2::ErrorMsg;
+import @3.2::MsgType;
+import @3.2::ShutterMsg;
+
+/**
+ * ShutterMsg:
+ *
+ * Message contents for MsgType::SHUTTER
+ *
+ * This version extends the @3.2 ShutterMsg with the readout timestamp.
+ */
+struct ShutterMsg {
+    /**
+     * The definition of ShutterMsg from prior version.
+     */
+    @3.2::ShutterMsg v3_2;
+
+    /**
+     * Timestamp for the capture readout. This must be in the same time domain
+     * as v3_2.timestamp, and for a rolling shutter sensor, the value must be
+     * v3_2.timestamp + exposureTime + t_crop_top where t_crop_top is the exposure time
+     * skew of the cropped lines on the top.
+     */
+    uint64_t readoutTimestamp;
+};
+
+/**
+ * NotifyMsg:
+ *
+ * The message structure sent to ICameraDevice3Callback::notify()
+ *
+ * This version extends the @3.2 NotifyMsg with the @3.8 version of ShutterMsg.
+ */
+struct NotifyMsg {
+    /**
+     * The message type.
+     */
+    @3.2::MsgType type;
+
+    union Message {
+        /**
+         * Error message contents. Valid if type is MsgType::ERROR
+         */
+        @3.2::ErrorMsg error;
+
+        /**
+         * Shutter message contents. Valid if type is MsgType::SHUTTER
+         */
+        ShutterMsg shutter;
+    } msg;
+};
diff --git a/camera/metadata/3.7/Android.bp b/camera/metadata/3.7/Android.bp
new file mode 100644
index 0000000..14981b8
--- /dev/null
+++ b/camera/metadata/3.7/Android.bp
@@ -0,0 +1,26 @@
+// 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.camera.metadata@3.7",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.metadata@3.2",
+        "android.hardware.camera.metadata@3.3",
+        "android.hardware.camera.metadata@3.4",
+        "android.hardware.camera.metadata@3.5",
+        "android.hardware.camera.metadata@3.6",
+    ],
+    gen_java: true,
+}
diff --git a/camera/metadata/3.8/Android.bp b/camera/metadata/3.8/Android.bp
new file mode 100644
index 0000000..ead9543
--- /dev/null
+++ b/camera/metadata/3.8/Android.bp
@@ -0,0 +1,27 @@
+// 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.camera.metadata@3.8",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.metadata@3.2",
+        "android.hardware.camera.metadata@3.3",
+        "android.hardware.camera.metadata@3.4",
+        "android.hardware.camera.metadata@3.5",
+        "android.hardware.camera.metadata@3.6",
+        "android.hardware.camera.metadata@3.7",
+    ],
+    gen_java: true,
+}
diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal
index dcee775..11360da 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -47,7 +47,7 @@
     /** android.flash.info.strengthDefaultLevel [static, int32, public]
      *
      * <p>Default flashlight brightness level to be set via
-     * {android.hardware.camera2.CameraManager#setTorchStrengthLevel}.</p>
+     * {android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel}.</p>
      */
     ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
 
@@ -58,3 +58,11 @@
 /*
  * Enumeration definitions for the various entries that need them
  */
+
+/** android.control.videoStabilizationMode enumeration values added since v3.2
+ * @see ANDROID_CONTROL_VIDEO_STABILIZATION_MODE
+ */
+enum CameraMetadataEnumAndroidControlVideoStabilizationMode :
+        @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode {
+    ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
+};
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 64a51f6..4fc7437 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -65,10 +65,10 @@
 
 } // anonymous namespace
 
-ExternalCameraProviderImpl_2_4::ExternalCameraProviderImpl_2_4() :
-        mCfg(ExternalCameraConfig::loadFromCfg()),
-        mHotPlugThread(this) {
-    mHotPlugThread.run("ExtCamHotPlug", PRIORITY_BACKGROUND);
+ExternalCameraProviderImpl_2_4::ExternalCameraProviderImpl_2_4()
+    : mCfg(ExternalCameraConfig::loadFromCfg()) {
+    mHotPlugThread = sp<HotplugThread>::make(this);
+    mHotPlugThread->run("ExtCamHotPlug", PRIORITY_BACKGROUND);
 
     mPreferredHal3MinorVersion =
         property_get_int32("ro.vendor.camera.external.hal3TrebleMinorVersion", 4);
@@ -88,7 +88,7 @@
 }
 
 ExternalCameraProviderImpl_2_4::~ExternalCameraProviderImpl_2_4() {
-    mHotPlugThread.requestExit();
+    mHotPlugThread->requestExit();
 }
 
 
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
index 8c79f68..f1d8003 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
@@ -102,7 +102,7 @@
     sp<ICameraProviderCallback> mCallbacks = nullptr;
     std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap; // camera id -> status
     const ExternalCameraConfig mCfg;
-    HotplugThread mHotPlugThread;
+    sp<HotplugThread> mHotPlugThread;
     int mPreferredHal3MinorVersion;
 };
 
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 8886ee1..2c141ee 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -49,6 +49,7 @@
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.device@3.6",
         "android.hardware.camera.device@3.7",
+        "android.hardware.camera.device@3.8",
         "android.hardware.camera.metadata@3.4",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.provider@2.5",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 62de3af..77974fc 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -43,6 +43,7 @@
 #include <android/hardware/camera/device/3.7/ICameraDevice.h>
 #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
+#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
 #include <android/hardware/camera/metadata/3.4/types.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
 #include <android/hardware/camera/provider/2.5/ICameraProvider.h>
@@ -194,6 +195,7 @@
 namespace {
     // "device@<version>/legacy/<id>"
     const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+    const int CAMERA_DEVICE_API_VERSION_3_8 = 0x308;
     const int CAMERA_DEVICE_API_VERSION_3_7 = 0x307;
     const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306;
     const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
@@ -201,6 +203,7 @@
     const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+    const char *kHAL3_8 = "3.8";
     const char *kHAL3_7 = "3.7";
     const char *kHAL3_6 = "3.6";
     const char *kHAL3_5 = "3.5";
@@ -238,7 +241,9 @@
             return -1;
         }
 
-        if (version.compare(kHAL3_7) == 0) {
+        if (version.compare(kHAL3_8) == 0) {
+            return CAMERA_DEVICE_API_VERSION_3_8;
+        } else if (version.compare(kHAL3_7) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_7;
         } else if (version.compare(kHAL3_6) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_6;
@@ -638,7 +643,7 @@
      }
  };
 
-    struct DeviceCb : public V3_5::ICameraDeviceCallback {
+    struct DeviceCb : public V3_8::ICameraDeviceCallback {
         DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
                 mParent(parent), mDeviceVersion(deviceVersion) {
             mStaticMetadata = staticMeta;
@@ -648,6 +653,7 @@
                 const hidl_vec<V3_4::CaptureResult>& results) override;
         Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
         Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
+        Return<void> notify_3_8(const hidl_vec<V3_8::NotifyMsg>& msgs) override;
 
         Return<void> requestStreamBuffers(
                 const hidl_vec<V3_5::BufferRequest>& bufReqs,
@@ -663,6 +669,8 @@
      private:
         bool processCaptureResultLocked(const CaptureResult& results,
                 hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
+        Return<void> notifyHelper(const hidl_vec<NotifyMsg>& msgs,
+                const std::vector<std::pair<bool, nsecs_t>>& readoutTimestamps);
 
         CameraHidlTest *mParent; // Parent object
         int mDeviceVersion;
@@ -936,6 +944,9 @@
             camera_metadata_ro_entry* streamConfigs,
             camera_metadata_ro_entry* maxResolutionStreamConfigs,
             const camera_metadata_t* staticMetadata);
+    void getPrivacyTestPatternModes(
+            const camera_metadata_t* staticMetadata,
+            std::unordered_set<int32_t>* privacyTestPatternModes/*out*/);
     static bool isColorCamera(const camera_metadata_t *metadata);
 
     static V3_2::DataspaceFlags getDataspace(PixelFormat format);
@@ -953,6 +964,9 @@
         // Set by notify() SHUTTER call.
         nsecs_t shutterTimestamp;
 
+        bool shutterReadoutTimestampValid;
+        nsecs_t shutterReadoutTimestamp;
+
         bool errorCodeValid;
         ErrorCode errorCode;
 
@@ -998,6 +1012,8 @@
 
         InFlightRequest() :
                 shutterTimestamp(0),
+                shutterReadoutTimestampValid(false),
+                shutterReadoutTimestamp(0),
                 errorCodeValid(false),
                 errorCode(ErrorCode::ERROR_BUFFER),
                 usePartialResult(false),
@@ -1015,6 +1031,8 @@
                 bool partialResults, uint32_t partialCount,
                 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
                 shutterTimestamp(0),
+                shutterReadoutTimestampValid(false),
+                shutterReadoutTimestamp(0),
                 errorCodeValid(false),
                 errorCode(ErrorCode::ERROR_BUFFER),
                 usePartialResult(partialResults),
@@ -1033,6 +1051,8 @@
                 const std::unordered_set<std::string>& extraPhysicalResult,
                 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
                 shutterTimestamp(0),
+                shutterReadoutTimestampValid(false),
+                shutterReadoutTimestamp(0),
                 errorCodeValid(false),
                 errorCode(ErrorCode::ERROR_BUFFER),
                 usePartialResult(partialResults),
@@ -1459,8 +1479,46 @@
     }
 }
 
+Return<void> CameraHidlTest::DeviceCb::notify_3_8(
+        const hidl_vec<V3_8::NotifyMsg>& msgs) {
+    hidl_vec<NotifyMsg> msgs3_2;
+    std::vector<std::pair<bool, nsecs_t>> readoutTimestamps;
+
+    nsecs_t count = msgs.size();
+    msgs3_2.resize(count);
+    readoutTimestamps.resize(count);
+
+    for (size_t i = 0; i < count; i++) {
+        msgs3_2[i].type = msgs[i].type;
+        switch (msgs[i].type) {
+            case MsgType::ERROR:
+                msgs3_2[i].msg.error = msgs[i].msg.error;
+                readoutTimestamps[i] = {false, 0};
+                break;
+            case MsgType::SHUTTER:
+                msgs3_2[i].msg.shutter = msgs[i].msg.shutter.v3_2;
+                readoutTimestamps[i] = {true, msgs[i].msg.shutter.readoutTimestamp};
+                break;
+        }
+    }
+
+    return notifyHelper(msgs3_2, readoutTimestamps);
+}
+
 Return<void> CameraHidlTest::DeviceCb::notify(
         const hidl_vec<NotifyMsg>& messages) {
+    std::vector<std::pair<bool, nsecs_t>> readoutTimestamps;
+    readoutTimestamps.resize(messages.size());
+    for (size_t i = 0; i < messages.size(); i++) {
+        readoutTimestamps[i] = {false, 0};
+    }
+
+    return notifyHelper(messages, readoutTimestamps);
+}
+
+Return<void> CameraHidlTest::DeviceCb::notifyHelper(
+        const hidl_vec<NotifyMsg>& messages,
+        const std::vector<std::pair<bool, nsecs_t>>& readoutTimestamps) {
     std::lock_guard<std::mutex> l(mParent->mLock);
 
     for (size_t i = 0; i < messages.size(); i++) {
@@ -1523,6 +1581,8 @@
                 }
                 InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
                 r->shutterTimestamp = messages[i].msg.shutter.timestamp;
+                r->shutterReadoutTimestampValid = readoutTimestamps[i].first;
+                r->shutterReadoutTimestamp = readoutTimestamps[i].second;
             }
                 break;
             default:
@@ -1937,6 +1997,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -1981,6 +2042,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2722,6 +2784,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2809,6 +2872,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2890,6 +2954,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3018,6 +3083,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3085,6 +3151,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3121,7 +3188,7 @@
                 castSession(session, deviceVersion, &sessionV3_3,
                         &sessionV3_4, &sessionV3_5, &sessionV3_6,
                         &sessionV3_7);
-                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) {
+                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) {
                     ASSERT_TRUE(sessionV3_7.get() != nullptr);
                 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
                     ASSERT_TRUE(sessionV3_6.get() != nullptr);
@@ -3187,6 +3254,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -4727,6 +4795,28 @@
             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
             ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
 
+            // For camera device 3.8 or newer, shutterReadoutTimestamp must be
+            // available, and it must be >= shutterTimestamp + exposureTime, and
+            // < shutterTimestamp + exposureTime + rollingShutterSkew / 2.
+            if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) {
+                ASSERT_TRUE(inflightReq.shutterReadoutTimestampValid);
+                ASSERT_FALSE(inflightReq.collectedResult.isEmpty());
+                if (inflightReq.collectedResult.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
+                    camera_metadata_entry_t exposureTimeResult = inflightReq.collectedResult.find(
+                            ANDROID_SENSOR_EXPOSURE_TIME);
+                    nsecs_t exposureToReadout =
+                            inflightReq.shutterReadoutTimestamp - inflightReq.shutterTimestamp;
+                    ASSERT_GE(exposureToReadout, exposureTimeResult.data.i64[0]);
+                    if (inflightReq.collectedResult.exists(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW)) {
+                        camera_metadata_entry_t rollingShutterSkew =
+                                inflightReq.collectedResult.find(
+                                        ANDROID_SENSOR_ROLLING_SHUTTER_SKEW);
+                        ASSERT_LT(exposureToReadout, exposureTimeResult.data.i64[0] +
+                                                             rollingShutterSkew.data.i64[0] / 2);
+                    }
+                }
+            }
+
             request.frameNumber++;
             // Empty settings should be supported after the first call
             // for repeating requests.
@@ -6219,6 +6309,7 @@
         std::string cameraId;
         int deviceVersion = getCameraDeviceVersionAndId(name, mProviderType, &cameraId);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8:
             case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
@@ -6762,6 +6853,25 @@
     ASSERT_TRUE(-ENOENT == retcode || 0 == retcode);
 }
 
+void CameraHidlTest::getPrivacyTestPatternModes(
+        const camera_metadata_t* staticMetadata,
+        std::unordered_set<int32_t>* privacyTestPatternModes/*out*/) {
+    ASSERT_NE(staticMetadata, nullptr);
+    ASSERT_NE(privacyTestPatternModes, nullptr);
+
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(
+            staticMetadata, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &entry);
+    ASSERT_TRUE(0 == retcode);
+
+    for (auto i = 0; i < entry.count; i++) {
+        if (entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR ||
+                entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK) {
+            privacyTestPatternModes->insert(entry.data.i32[i]);
+        }
+    }
+}
+
 // Select an appropriate dataspace given a specific pixel format.
 V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) {
     switch (format) {
@@ -7629,6 +7739,7 @@
     ASSERT_NE(nullptr, device3_7);
 
     switch (deviceVersion) {
+        case CAMERA_DEVICE_API_VERSION_3_8:
         case CAMERA_DEVICE_API_VERSION_3_7: {
             auto castResult = device::V3_7::ICameraDevice::castFrom(device);
             ASSERT_TRUE(castResult.isOk());
@@ -7685,6 +7796,7 @@
     ASSERT_NE(nullptr, session3_7);
 
     switch (deviceVersion) {
+        case CAMERA_DEVICE_API_VERSION_3_8:
         case CAMERA_DEVICE_API_VERSION_3_7: {
             auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session);
             ASSERT_TRUE(castResult.isOk());
@@ -7816,6 +7928,16 @@
         ASSERT_TRUE(isUltraHighResCamera && !isMultiCamera);
         physicalIds.insert(cameraId);
     }
+
+    std::unordered_set<int32_t> physicalRequestKeyIDs;
+    rc = getSupportedKeys(const_cast<camera_metadata_t *>(metadata),
+            ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
+    ASSERT_TRUE(Status::OK == rc);
+    bool hasTestPatternPhysicalRequestKey = physicalRequestKeyIDs.find(
+            ANDROID_SENSOR_TEST_PATTERN_MODE) != physicalRequestKeyIDs.end();
+    std::unordered_set<int32_t> privacyTestPatternModes;
+    getPrivacyTestPatternModes(metadata, &privacyTestPatternModes);
+
     // Map from image format to number of multi-resolution sizes for that format
     std::unordered_map<int32_t, size_t> multiResOutputFormatCounterMap;
     std::unordered_map<int32_t, size_t> multiResInputFormatCounterMap;
@@ -7837,6 +7959,7 @@
         camera_metadata_ro_entry physicalStreamConfigs;
         camera_metadata_ro_entry physicalMaxResolutionStreamConfigs;
         bool isUltraHighRes = false;
+        std::unordered_set<int32_t> subCameraPrivacyTestPatterns;
         if (isPublicId) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> subDevice;
             Return<void> ret;
@@ -7867,6 +7990,8 @@
                         &physicalMultiResStreamConfigs, &physicalStreamConfigs,
                         &physicalMaxResolutionStreamConfigs, staticMetadata);
                 isUltraHighRes = isUltraHighResolution(staticMetadata);
+
+                getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
             });
             ASSERT_TRUE(ret.isOk());
         } else {
@@ -7893,6 +8018,7 @@
                                 &physicalMultiResStreamConfigs, &physicalStreamConfigs,
                                 &physicalMaxResolutionStreamConfigs, staticMetadata);
                         isUltraHighRes = isUltraHighResolution(staticMetadata);
+                        getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
                     });
             ASSERT_TRUE(ret.isOk());
 
@@ -7909,6 +8035,10 @@
             ASSERT_TRUE(ret.isOk());
         }
 
+        if (hasTestPatternPhysicalRequestKey) {
+            ASSERT_TRUE(privacyTestPatternModes == subCameraPrivacyTestPatterns);
+        }
+
         if (physicalMultiResStreamConfigs.count > 0) {
             ASSERT_GE(deviceVersion, CAMERA_DEVICE_API_VERSION_3_7);
             ASSERT_EQ(physicalMultiResStreamConfigs.count % 4, 0);
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index a59be21..193fd2b 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -81,5 +81,6 @@
     ],
     kernel_configs: [
         "kernel_config_current_5.10",
+        "kernel_config_current_5.15",
     ],
 }
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 7ae1425..9dc6fae 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -147,6 +147,13 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.boot</name>
         <version>1.2</version>
@@ -222,9 +229,8 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="aidl" optional="true">
         <name>android.hardware.dumpstate</name>
-        <version>1.1</version>
         <interface>
             <name>IDumpstateDevice</name>
             <instance>default</instance>
@@ -248,6 +254,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.gnss</name>
+        <version>2</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
@@ -435,7 +442,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.neuralnetworks</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>IDevice</name>
             <regex-instance>.*</regex-instance>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 2aa4bb2..720a767 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -56,6 +56,7 @@
             "android.hardware.common",
             "android.hardware.common.fmq",
             "android.hardware.graphics.common",
+            "android.hardware.graphics.composer3.command",
             "android.hardware.keymaster",
             "android.hardware.radio",
             "android.hardware.uwb.fira_android",
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
index 0c6c513..e7dcbc7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -31,15 +31,16 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.contexthub;
+@VintfStability
+parcelable HostEndpointInfo {
+  char hostEndpointId;
+  android.hardware.contexthub.HostEndpointInfo.Type type;
+  @nullable String packageName;
+  @nullable String attributionTag;
+  @Backing(type="int") @VintfStability
+  enum Type {
+    TYPE_FRAMEWORK = 1,
+    TYPE_APP = 2,
+  }
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index cb31c84..facce4b 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -43,4 +43,6 @@
   boolean queryNanoapps(in int contextHubId);
   boolean registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb);
   boolean sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
+  void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
+  void onHostEndpointDisconnected(char hostEndpointId);
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
new file mode 100644
index 0000000..40a231d
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+/**
+ * Stores metadata regarding a host endpoint that may communicate with the Context Hub.
+ */
+@VintfStability
+parcelable HostEndpointInfo {
+    /** The ID of the host endpoint asscociated with this host. */
+    char hostEndpointId;
+
+    /** The type of endpoint. */
+    Type type;
+
+    /** The (optional) package name of the host. */
+    @nullable String packageName;
+
+    /** The (optional) attribution tag associated with this host. */
+    @nullable String attributionTag;
+
+    @VintfStability
+    @Backing(type="int")
+    enum Type {
+        /**
+           This endpoint is from the Android framework, where packageName and attributionTag may be
+           empty.
+         */
+        TYPE_FRAMEWORK = 1,
+
+        /** This endpoint is an Android app. */
+        TYPE_APP = 2,
+    }
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index e820cbf..33d241a 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.contexthub.ContextHubInfo;
 import android.hardware.contexthub.ContextHubMessage;
+import android.hardware.contexthub.HostEndpointInfo;
 import android.hardware.contexthub.IContextHubCallback;
 import android.hardware.contexthub.NanoappBinary;
 import android.hardware.contexthub.Setting;
@@ -151,4 +152,29 @@
      * @return true on success
      */
     boolean sendMessageToHub(in int contextHubId, in ContextHubMessage message);
+
+    /**
+     * Invoked when a host endpoint has connected with the ContextHubService.
+     *
+     * The host associated with this invocation may initiate a communication channel with
+     * the Context Hub using sendMessageToHub.
+     *
+     * @param hostEndpointInfo Metadata associated with this host endpoint.
+     */
+    void onHostEndpointConnected(in HostEndpointInfo hostEndpointInfo);
+
+    /**
+     * Invoked when a host endpoint has disconnected from the framework. This could be as a result
+     * of an explicit connection closure, or unexpected restarts.
+     *
+     * Note that hostEndpointId is the same as the value in HostEndpointInfo. When this function is
+     * called, the HAL is expected to clean up any resources attached to the messaging channel
+     * associated with this host endpoint ID.
+     *
+     * @param hostEndPointId The ID of the host that has disconnected.
+     *
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host.
+     */
+    void onHostEndpointDisconnected(char hostEndpointId);
 }
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 1fbccc5..6da690d 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -111,6 +111,21 @@
     return ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
+    mConnectedHostEndpoints.insert(in_info.hostEndpointId);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
+    if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
+        mConnectedHostEndpoints.erase(in_hostEndpointId);
+        return ndk::ScopedAStatus::ok();
+    } else {
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
+    }
+}
+
 }  // namespace contexthub
 }  // namespace hardware
 }  // namespace android
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 0dbb61b..dd739e6 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -18,6 +18,8 @@
 
 #include <aidl/android/hardware/contexthub/BnContextHub.h>
 
+#include <unordered_set>
+
 namespace aidl {
 namespace android {
 namespace hardware {
@@ -41,10 +43,15 @@
     ::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId,
                                           const ContextHubMessage& in_message,
                                           bool* _aidl_return) override;
+    ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override;
+
+    ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
 
   private:
     static constexpr uint32_t kMockHubId = 0;
     std::shared_ptr<IContextHubCallback> mCallback;
+
+    std::unordered_set<char16_t> mConnectedHostEndpoints;
 };
 
 }  // namespace contexthub
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 4b0d60f..1b2dc29 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -36,6 +36,7 @@
 using ::android::hardware::contexthub::AsyncEventType;
 using ::android::hardware::contexthub::ContextHubInfo;
 using ::android::hardware::contexthub::ContextHubMessage;
+using ::android::hardware::contexthub::HostEndpointInfo;
 using ::android::hardware::contexthub::IContextHub;
 using ::android::hardware::contexthub::IContextHubCallbackDefault;
 using ::android::hardware::contexthub::NanoappBinary;
@@ -330,6 +331,22 @@
     return tuples;
 }
 
+TEST_P(ContextHubAidl, TestHostConnection) {
+    constexpr char16_t kHostEndpointId = 1;
+    HostEndpointInfo hostEndpointInfo;
+    hostEndpointInfo.hostEndpointId = kHostEndpointId;
+
+    ASSERT_TRUE(contextHub->onHostEndpointConnected(hostEndpointInfo).isOk());
+    ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
+}
+
+TEST_P(ContextHubAidl, TestInvalidHostConnection) {
+    constexpr char16_t kHostEndpointId = 1;
+
+    Status status = contextHub->onHostEndpointDisconnected(kHostEndpointId);
+    ASSERT_EQ(status.exceptionCode(), android::binder::Status::EX_ILLEGAL_ARGUMENT);
+}
+
 std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
     return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
 }
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
new file mode 100644
index 0000000..e18eade
--- /dev/null
+++ b/dumpstate/aidl/Android.bp
@@ -0,0 +1,43 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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.dumpstate",
+    vendor_available: true,
+    srcs: ["android/hardware/dumpstate/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            separate_platform_variant: false,
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.aidl
similarity index 73%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.aidl
index 0c6c513..4d78a4c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.aidl
@@ -31,15 +31,23 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.dumpstate;
+@VintfStability
+interface IDumpstateDevice {
+  void dumpstateBoard(in ParcelFileDescriptor[] fd, in android.hardware.dumpstate.IDumpstateDevice.DumpstateMode mode, in long timeoutMillis);
+  boolean getVerboseLoggingEnabled();
+  void setVerboseLoggingEnabled(in boolean enable);
+  const int ERROR_UNSUPPORTED_MODE = 1;
+  const int ERROR_DEVICE_LOGGING_NOT_ENABLED = 2;
+  @Backing(type="int") @VintfStability
+  enum DumpstateMode {
+    FULL = 0,
+    INTERACTIVE = 1,
+    REMOTE = 2,
+    WEAR = 3,
+    CONNECTIVITY = 4,
+    WIFI = 5,
+    DEFAULT = 6,
+    PROTO = 7,
+  }
 }
diff --git a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
new file mode 100644
index 0000000..3b42546
--- /dev/null
+++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
@@ -0,0 +1,137 @@
+/*
+ * 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.dumpstate;
+
+import android.os.ParcelFileDescriptor;
+
+@VintfStability
+interface IDumpstateDevice {
+    /**
+     * Constants that define the type of bug report being taken to restrict content appropriately.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum DumpstateMode {
+        /**
+         * Takes a bug report without user interference.
+         */
+        FULL = 0,
+        /**
+         * Interactive bug report, i.e. triggered by the user.
+         */
+        INTERACTIVE = 1,
+        /**
+         * Remote bug report triggered by DevicePolicyManager, for example.
+         */
+        REMOTE = 2,
+        /**
+         * Bug report triggered on a wear device.
+         */
+        WEAR = 3,
+        /**
+         * Bug report limited to only connectivity info (cellular, wifi, and networking). Sometimes
+         * called "telephony" in legacy contexts.
+         *
+         * All reported information MUST directly relate to connectivity debugging or customer
+         * support and MUST NOT contain unrelated private information. This information MUST NOT
+         * identify user-installed packages (UIDs are OK, package names are not), and MUST NOT
+         * contain logs of user application traffic.
+         */
+        CONNECTIVITY = 4,
+        /**
+         * Bug report limited to only wifi info.
+         */
+        WIFI = 5,
+        /**
+         * Default mode, This mode MUST be supported if the
+         * dumpstate HAL is implemented.
+         */
+        DEFAULT = 6,
+        /**
+         * Takes a report in protobuf.
+         *
+         * The content, if implemented, must be a binary protobuf message written to the first file
+         * descriptor of the native handle. The protobuf schema shall be defined by the vendor.
+         */
+        PROTO = 7,
+    }
+
+    /**
+     * Returned for cases where the device doesn't support the given DumpstateMode (e.g. a phone
+     * trying to use DumpstateMode::WEAR).
+     */
+    const int ERROR_UNSUPPORTED_MODE = 1;
+    /**
+     * Returned when device logging is not enabled.
+     */
+    const int ERROR_DEVICE_LOGGING_NOT_ENABLED = 2;
+
+    /**
+     * Dump device-specific state into the given file descriptors.
+     *
+     * One file descriptor must be passed to this method but two may be passed:
+     * the first descriptor must be used to dump device-specific state in text
+     * format, the second descriptor is optional and may be used to dump
+     * device-specific state in binary format.
+     *
+     * DumpstateMode can be used to limit the information that is output.
+     * For an example of when this is relevant, consider a bug report being generated with
+     * DumpstateMode::CONNECTIVITY - there is no reason to include camera or USB logs in this type
+     * of report.
+     *
+     * When verbose logging is disabled, getVerboseLoggingEnabled returns false, and this
+     * API is called, it may still output essential information but must not include
+     * information that identifies the user.
+     *
+     * @param fd array of file descriptors, with one or two valid file descriptors. The first FD is
+     *         for text output, the second (if present) is for binary output.
+     * @param mode A mode value to restrict dumped content.
+     * @param timeoutMillis An approximate "budget" for how much time this call has been allotted.
+     *     If execution runs longer than this, the IDumpstateDevice service may be killed and only
+     *     partial information will be included in the report.
+     * @return If error, return service specific error with code
+     *           ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED
+     */
+    void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis);
+
+    /**
+     * Queries the current state of verbose device logging. Primarily for UI and informative
+     * purposes.
+     *
+     * Even if verbose logging has been disabled, dumpstateBoard may still be called by the
+     * dumpstate routine, and essential information that does not identify the user may be included.
+     *
+     * @return Whether or not verbose vendor logging is currently enabled.
+     */
+    boolean getVerboseLoggingEnabled();
+
+    /**
+     * Turns verbose device vendor logging on or off.
+     *
+     * The setting should be persistent across reboots. Underlying implementations may need to start
+     * vendor logging daemons, set system properties, or change logging masks, for example. Given
+     * that many vendor logs contain significant amounts of private information and may come with
+     * memory/storage/battery impacts, calling this method on a user build should only be done after
+     * user consent has been obtained, e.g. from a toggle in developer settings.
+     *
+     * Even if verbose logging has been disabled, dumpstateBoard may still be called by the
+     * dumpstate routine, and essential information that does not identify the user may be included.
+     *
+     * @param enable Whether to enable or disable verbose vendor logging.
+     */
+    void setVerboseLoggingEnabled(in boolean enable);
+}
diff --git a/dumpstate/aidl/default/Android.bp b/dumpstate/aidl/default/Android.bp
new file mode 100644
index 0000000..45fdc17
--- /dev/null
+++ b/dumpstate/aidl/default/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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.dumpstate-service.example",
+    relative_install_path: "hw",
+    init_rc: ["dumpstate-default.rc"],
+    vintf_fragments: ["dumpstate-default.xml"],
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libdumpstateutil",
+        "liblog",
+        "libutils",
+        "android.hardware.dumpstate-V1-ndk",
+    ],
+    srcs: [
+        "main.cpp",
+        "Dumpstate.cpp",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"android.hardware.dumpstate-service.example\"",
+    ],
+}
diff --git a/dumpstate/aidl/default/Dumpstate.cpp b/dumpstate/aidl/default/Dumpstate.cpp
new file mode 100644
index 0000000..a0730fb
--- /dev/null
+++ b/dumpstate/aidl/default/Dumpstate.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/properties.h>
+#include <log/log.h>
+#include "DumpstateUtil.h"
+
+#include "Dumpstate.h"
+
+using android::os::dumpstate::DumpFileToFd;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace dumpstate {
+
+const char kVerboseLoggingProperty[] = "persist.dumpstate.verbose_logging.enabled";
+
+ndk::ScopedAStatus Dumpstate::dumpstateBoard(const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+                                             IDumpstateDevice::DumpstateMode in_mode,
+                                             int64_t in_timeoutMillis) {
+    (void)in_timeoutMillis;
+
+    if (in_fds.size() < 1) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "No file descriptor");
+    }
+
+    int fd = in_fds[0].get();
+    if (fd < 0) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid file descriptor");
+    }
+
+    switch (in_mode) {
+        case IDumpstateDevice::DumpstateMode::FULL:
+            return dumpstateBoardImpl(fd, true);
+
+        case IDumpstateDevice::DumpstateMode::DEFAULT:
+            return dumpstateBoardImpl(fd, false);
+
+        case IDumpstateDevice::DumpstateMode::INTERACTIVE:
+        case IDumpstateDevice::DumpstateMode::REMOTE:
+        case IDumpstateDevice::DumpstateMode::WEAR:
+        case IDumpstateDevice::DumpstateMode::CONNECTIVITY:
+        case IDumpstateDevice::DumpstateMode::WIFI:
+        case IDumpstateDevice::DumpstateMode::PROTO:
+            return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(ERROR_UNSUPPORTED_MODE,
+                                                                           "Unsupported mode");
+
+        default:
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Invalid mode");
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Dumpstate::getVerboseLoggingEnabled(bool* _aidl_return) {
+    *_aidl_return = getVerboseLoggingEnabledImpl();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Dumpstate::setVerboseLoggingEnabled(bool in_enable) {
+    ::android::base::SetProperty(kVerboseLoggingProperty, in_enable ? "true" : "false");
+    return ndk::ScopedAStatus::ok();
+}
+
+bool Dumpstate::getVerboseLoggingEnabledImpl() {
+    return ::android::base::GetBoolProperty(kVerboseLoggingProperty, false);
+}
+
+ndk::ScopedAStatus Dumpstate::dumpstateBoardImpl(const int fd, const bool full) {
+    ALOGD("DumpstateDevice::dumpstateBoard() FD: %d\n", fd);
+
+    dprintf(fd, "verbose logging: %s\n", getVerboseLoggingEnabledImpl() ? "enabled" : "disabled");
+    dprintf(fd, "[%s] %s\n", (full ? "full" : "default"), "Hello, world!");
+
+    // Shows an example on how to use the libdumpstateutil API.
+    DumpFileToFd(fd, "cmdline", "/proc/self/cmdline");
+
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace dumpstate
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/dumpstate/aidl/default/Dumpstate.h b/dumpstate/aidl/default/Dumpstate.h
new file mode 100644
index 0000000..0629831
--- /dev/null
+++ b/dumpstate/aidl/default/Dumpstate.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/dumpstate/BnDumpstateDevice.h>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android/binder_status.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace dumpstate {
+
+class Dumpstate : public BnDumpstateDevice {
+  private:
+    bool getVerboseLoggingEnabledImpl();
+    ::ndk::ScopedAStatus dumpstateBoardImpl(const int fd, const bool full);
+
+  public:
+    ::ndk::ScopedAStatus dumpstateBoard(const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+                                        IDumpstateDevice::DumpstateMode in_mode,
+                                        int64_t in_timeoutMillis) override;
+
+    ::ndk::ScopedAStatus getVerboseLoggingEnabled(bool* _aidl_return) override;
+
+    ::ndk::ScopedAStatus setVerboseLoggingEnabled(bool in_enable) override;
+};
+
+}  // namespace dumpstate
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/dumpstate/aidl/default/dumpstate-default.rc b/dumpstate/aidl/default/dumpstate-default.rc
new file mode 100644
index 0000000..4d011dd
--- /dev/null
+++ b/dumpstate/aidl/default/dumpstate-default.rc
@@ -0,0 +1,7 @@
+service vendor.dumpstate-default /vendor/bin/hw/android.hardware.dumpstate-service.example
+    class hal
+    user nobody
+    group nobody
+    interface aidl android.hardware.dumpstate.IDumpstateDevice/default
+    oneshot
+    disabled
diff --git a/dumpstate/aidl/default/dumpstate-default.xml b/dumpstate/aidl/default/dumpstate-default.xml
new file mode 100644
index 0000000..877aeed
--- /dev/null
+++ b/dumpstate/aidl/default/dumpstate-default.xml
@@ -0,0 +1,8 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.dumpstate</name>
+        <version>1</version>
+        <fqname>IDumpstateDevice/default</fqname>
+    </hal>
+</manifest>
+
diff --git a/dumpstate/aidl/default/main.cpp b/dumpstate/aidl/default/main.cpp
new file mode 100644
index 0000000..2451752
--- /dev/null
+++ b/dumpstate/aidl/default/main.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Dumpstate.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::dumpstate::Dumpstate;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Dumpstate> dumpstate = ndk::SharedRefBase::make<Dumpstate>();
+
+    const std::string instance = std::string() + Dumpstate::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_registerLazyService(dumpstate->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // Unreachable
+}
diff --git a/dumpstate/aidl/vts/functional/Android.bp b/dumpstate/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..5e516cf
--- /dev/null
+++ b/dumpstate/aidl/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalDumpstateTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalDumpstateTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvintf",
+    ],
+    static_libs: [
+        "android.hardware.dumpstate-V1-ndk",
+    ],
+    test_suites: [
+        "vts",
+    ],
+}
diff --git a/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp b/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp
new file mode 100644
index 0000000..442b0b0
--- /dev/null
+++ b/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <functional>
+#include <tuple>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::dumpstate::IDumpstateDevice;
+
+// Base class common to all dumpstate HAL AIDL tests.
+template <typename T>
+class DumpstateAidlTestBase : public ::testing::TestWithParam<T> {
+  protected:
+    bool CheckStatus(const ndk::ScopedAStatus& status, const binder_exception_t expected_ex_code,
+                     const int32_t expected_service_specific) {
+        binder_exception_t ex_code = status.getExceptionCode();
+        if (ex_code != expected_ex_code) {
+            return false;
+        }
+        if (ex_code == EX_SERVICE_SPECIFIC) {
+            int32_t service_specific = status.getServiceSpecificError();
+            if (service_specific != expected_service_specific) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+  public:
+    virtual void SetUp() override { GetService(); }
+
+    virtual std::string GetInstanceName() = 0;
+
+    void GetService() {
+        const std::string instance_name = GetInstanceName();
+
+        ASSERT_TRUE(AServiceManager_isDeclared(instance_name.c_str()));
+        auto dumpstateBinder =
+                ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str()));
+        dumpstate = IDumpstateDevice::fromBinder(dumpstateBinder);
+        ASSERT_NE(dumpstate, nullptr) << "Could not get AIDL instance " << instance_name;
+    }
+
+    void ToggleVerboseLogging(bool enable) {
+        ndk::ScopedAStatus status;
+        bool logging_enabled = false;
+
+        status = dumpstate->setVerboseLoggingEnabled(enable);
+        ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.getDescription();
+
+        status = dumpstate->getVerboseLoggingEnabled(&logging_enabled);
+        ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.getDescription();
+        ASSERT_EQ(logging_enabled, enable)
+                << "Verbose logging should now be " << (enable ? "enabled" : "disabled");
+    }
+
+    void EnableVerboseLogging() { ToggleVerboseLogging(true); }
+
+    void DisableVerboseLogging() { ToggleVerboseLogging(false); }
+
+    std::shared_ptr<IDumpstateDevice> dumpstate;
+};
+
+// Tests that don't need to iterate every single DumpstateMode value for dumpstateBoard_1_1.
+class DumpstateAidlGeneralTest : public DumpstateAidlTestBase<std::string> {
+  protected:
+    virtual std::string GetInstanceName() override { return GetParam(); }
+};
+
+// Tests that iterate every single DumpstateMode value for dumpstateBoard_1_1.
+class DumpstateAidlPerModeTest
+    : public DumpstateAidlTestBase<std::tuple<std::string, IDumpstateDevice::DumpstateMode>> {
+  protected:
+    virtual std::string GetInstanceName() override { return std::get<0>(GetParam()); }
+
+    IDumpstateDevice::DumpstateMode GetMode() { return std::get<1>(GetParam()); }
+
+    // Will only execute additional_assertions when status == expected.
+    void AssertStatusForMode(const ::ndk::ScopedAStatus& status,
+                             binder_exception_t expected_ex_code, int32_t expected_service_specific,
+                             std::function<void()> additional_assertions = nullptr) {
+        if (GetMode() == IDumpstateDevice::DumpstateMode::DEFAULT) {
+            ASSERT_TRUE(CheckStatus(status, expected_ex_code, expected_ex_code));
+        } else {
+            // The rest of the modes are optional to support, but they MUST return either the
+            // expected value or UNSUPPORTED_MODE.
+            ASSERT_TRUE(CheckStatus(status, expected_ex_code, expected_service_specific) ||
+                        CheckStatus(status, EX_SERVICE_SPECIFIC,
+                                    IDumpstateDevice::ERROR_UNSUPPORTED_MODE));
+        }
+        if (CheckStatus(status, expected_ex_code, expected_service_specific) &&
+            additional_assertions != nullptr) {
+            additional_assertions();
+        }
+    }
+};
+
+constexpr uint64_t kDefaultTimeoutMillis = 30 * 1000;  // 30 seconds
+
+// Negative test: make sure dumpstateBoard() doesn't crash when passed a empty file descriptor
+// array.
+TEST_P(DumpstateAidlPerModeTest, TestNullHandle) {
+    EnableVerboseLogging();
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;  // empty file descriptor vector
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+    AssertStatusForMode(status, EX_ILLEGAL_ARGUMENT, 0);
+}
+
+// Positive test: make sure dumpstateBoard() writes something to the FD.
+TEST_P(DumpstateAidlPerModeTest, TestOk) {
+    EnableVerboseLogging();
+
+    // Index 0 corresponds to the read end of the pipe; 1 to the write end.
+    int fds[2];
+    ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+    dumpstateFds.emplace_back(fds[1]);
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+    AssertStatusForMode(status, EX_NONE, 0, [&fds]() {
+        // Check that at least one byte was written.
+        char buff;
+        ASSERT_EQ(1, read(fds[0], &buff, 1)) << "Dumped nothing";
+    });
+
+    close(fds[1]);
+    close(fds[0]);
+}
+
+// Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
+TEST_P(DumpstateAidlPerModeTest, TestHandleWithTwoFds) {
+    EnableVerboseLogging();
+
+    int fds1[2];
+    int fds2[2];
+    ASSERT_EQ(0, pipe2(fds1, O_NONBLOCK)) << errno;
+    ASSERT_EQ(0, pipe2(fds2, O_NONBLOCK)) << errno;
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+    dumpstateFds.emplace_back(fds1[1]);
+    dumpstateFds.emplace_back(fds2[1]);
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+    AssertStatusForMode(status, EX_NONE, 0, [&fds1, &fds2]() {
+        // Check that at least one byte was written to one of the FDs.
+        char buff;
+        size_t read1 = read(fds1[0], &buff, 1);
+        size_t read2 = read(fds2[0], &buff, 1);
+        // Sometimes read returns -1, so we can't just add them together and expect >= 1.
+        ASSERT_TRUE(read1 == 1 || read2 == 1) << "Dumped nothing";
+    });
+
+    close(fds1[1]);
+    close(fds1[0]);
+    close(fds2[1]);
+    close(fds2[0]);
+}
+
+// Make sure dumpstateBoard actually validates its arguments.
+TEST_P(DumpstateAidlGeneralTest, TestInvalidModeArgument_Negative) {
+    EnableVerboseLogging();
+
+    int fds[2];
+    ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+    dumpstateFds.emplace_back(fds[1]);
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds,
+                                            static_cast<IDumpstateDevice::DumpstateMode>(-100),
+                                            kDefaultTimeoutMillis);
+    ASSERT_TRUE(CheckStatus(status, EX_ILLEGAL_ARGUMENT, 0));
+
+    close(fds[1]);
+    close(fds[0]);
+}
+
+TEST_P(DumpstateAidlGeneralTest, TestInvalidModeArgument_Undefined) {
+    EnableVerboseLogging();
+
+    int fds[2];
+    ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+    dumpstateFds.emplace_back(fds[1]);
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds,
+                                            static_cast<IDumpstateDevice::DumpstateMode>(9001),
+                                            kDefaultTimeoutMillis);
+    ASSERT_TRUE(CheckStatus(status, EX_ILLEGAL_ARGUMENT, 0));
+
+    close(fds[1]);
+    close(fds[0]);
+}
+
+// Make sure disabling verbose logging behaves correctly. Some info is still allowed to be emitted,
+// but it can't have privacy/storage/battery impacts.
+TEST_P(DumpstateAidlPerModeTest, TestDeviceLoggingDisabled) {
+    DisableVerboseLogging();
+
+    // Index 0 corresponds to the read end of the pipe; 1 to the write end.
+    int fds[2];
+    ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+    std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+    dumpstateFds.emplace_back(fds[1]);
+
+    auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+    // We don't include additional assertions here about the file passed in. If verbose logging is
+    // disabled, the OEM may choose to include nothing at all, but it is allowed to include some
+    // essential information based on the mode as long as it isn't private user information.
+    AssertStatusForMode(status, EX_NONE, 0);
+
+    close(fds[1]);
+    close(fds[0]);
+}
+
+// Double-enable is perfectly valid, but the second call shouldn't do anything.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedEnable) {
+    EnableVerboseLogging();
+    EnableVerboseLogging();
+}
+
+// Double-disable is perfectly valid, but the second call shouldn't do anything.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedDisable) {
+    DisableVerboseLogging();
+    DisableVerboseLogging();
+}
+
+// Toggling in short order is perfectly valid.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedToggle) {
+    EnableVerboseLogging();
+    DisableVerboseLogging();
+    EnableVerboseLogging();
+    DisableVerboseLogging();
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateAidlGeneralTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, DumpstateAidlGeneralTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IDumpstateDevice::descriptor)),
+        android::PrintInstanceNameToString);
+
+// Includes the mode's name as part of the description string.
+static inline std::string PrintInstanceNameToStringWithMode(
+        const testing::TestParamInfo<std::tuple<std::string, IDumpstateDevice::DumpstateMode>>&
+                info) {
+    return android::PrintInstanceNameToString(
+                   testing::TestParamInfo(std::get<0>(info.param), info.index)) +
+           "_" + toString(std::get<1>(info.param));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateAidlPerModeTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstanceAndMode, DumpstateAidlPerModeTest,
+        testing::Combine(
+                testing::ValuesIn(android::getAidlHalInstanceNames(IDumpstateDevice::descriptor)),
+                testing::ValuesIn(ndk::internal::enum_values<IDumpstateDevice::DumpstateMode>)),
+        PrintInstanceNameToStringWithMode);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 3c9c29a..a73182e 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -27,7 +27,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 695246a..769e8ae 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -50,7 +50,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index c46c735..2979f5c 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -44,7 +44,7 @@
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
similarity index 70%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
index d7eecbb..54c126c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
@@ -31,8 +31,27 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable GnssLocation {
+  int gnssLocationFlags;
+  double latitudeDegrees;
+  double longitudeDegrees;
+  double altitudeMeters;
+  double speedMetersPerSec;
+  double bearingDegrees;
+  double horizontalAccuracyMeters;
+  double verticalAccuracyMeters;
+  double speedAccuracyMetersPerSecond;
+  double bearingAccuracyDegrees;
+  long timestampMillis;
+  android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+  const int HAS_LAT_LONG = 1;
+  const int HAS_ALTITUDE = 2;
+  const int HAS_SPEED = 4;
+  const int HAS_BEARING = 8;
+  const int HAS_HORIZONTAL_ACCURACY = 16;
+  const int HAS_VERTICAL_ACCURACY = 32;
+  const int HAS_SPEED_ACCURACY = 64;
+  const int HAS_BEARING_ACCURACY = 128;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
similarity index 76%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index d7eecbb..f02e08c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -31,8 +31,19 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IAGnss {
+  void setCallback(in android.hardware.gnss.IAGnssCallback callback);
+  void dataConnClosed();
+  void dataConnFailed();
+  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in String hostname, in int port);
+  void dataConnOpen(in long networkHandle, in String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+  @Backing(type="int") @VintfStability
+  enum ApnIpType {
+    INVALID = 0,
+    IPV4 = 1,
+    IPV6 = 2,
+    IPV4V6 = 3,
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
index d7eecbb..2a46f61 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
@@ -31,8 +31,23 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IAGnssCallback {
+  void agnssStatusCb(in android.hardware.gnss.IAGnssCallback.AGnssType type, in android.hardware.gnss.IAGnssCallback.AGnssStatusValue status);
+  @Backing(type="int") @VintfStability
+  enum AGnssType {
+    SUPL = 1,
+    C2K = 2,
+    SUPL_EIMS = 3,
+    SUPL_IMS = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum AGnssStatusValue {
+    REQUEST_AGNSS_DATA_CONN = 1,
+    RELEASE_AGNSS_DATA_CONN = 2,
+    AGNSS_DATA_CONNECTED = 3,
+    AGNSS_DATA_CONN_DONE = 4,
+    AGNSS_DATA_CONN_FAILED = 5,
+  }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index f93b496..ea98030 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -36,10 +36,14 @@
 interface IGnss {
   void setCallback(in android.hardware.gnss.IGnssCallback callback);
   void close();
-  android.hardware.gnss.IGnssPsds getExtensionPsds();
+  @nullable android.hardware.gnss.IGnssPsds getExtensionPsds();
   android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
   android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
   android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
+  @nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
+  @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
+  @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+  android.hardware.gnss.IAGnss getExtensionAGnss();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
index d7eecbb..492edc3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
@@ -31,8 +31,14 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssBatching {
+  void init(in android.hardware.gnss.IGnssBatchingCallback callback);
+  int getBatchSize();
+  void start(in long periodNanos, in int flags);
+  void flush();
+  void stop();
+  void cleanup();
+  const int WAKEUP_ON_FIFO_FULL = 1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
similarity index 91%
rename from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
index d7eecbb..427137a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -31,8 +31,8 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssBatchingCallback {
+  void gnssLocationBatchCb(in android.hardware.gnss.GnssLocation[] locations);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
similarity index 76%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
index d7eecbb..50da5bf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssGeofence {
+  void setCallback(in android.hardware.gnss.IGnssGeofenceCallback callback);
+  void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees, in double radiusMeters, in int lastTransition, in int monitorTransitions, in int notificationResponsivenessMs, in int unknownTimerMs);
+  void pauseGeofence(in int geofenceId);
+  void resumeGeofence(in int geofenceId, in int monitorTransitions);
+  void removeGeofence(in int geofenceId);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
similarity index 64%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
index d7eecbb..26482ea 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -31,8 +31,24 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssGeofenceCallback {
+  void gnssGeofenceTransitionCb(in int geofenceId, in android.hardware.gnss.GnssLocation location, in int transition, in long timestampMillis);
+  void gnssGeofenceStatusCb(in int availability, in android.hardware.gnss.GnssLocation lastLocation);
+  void gnssGeofenceAddCb(in int geofenceId, in int status);
+  void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+  void gnssGeofencePauseCb(in int geofenceId, in int status);
+  void gnssGeofenceResumeCb(in int geofenceId, in int status);
+  const int ENTERED = 1;
+  const int EXITED = 2;
+  const int UNCERTAIN = 4;
+  const int UNAVAILABLE = 1;
+  const int AVAILABLE = 2;
+  const int OPERATION_SUCCESS = 0;
+  const int ERROR_TOO_MANY_GEOFENCES = -100;
+  const int ERROR_ID_EXISTS = -101;
+  const int ERROR_ID_UNKNOWN = -102;
+  const int ERROR_INVALID_TRANSITION = -103;
+  const int ERROR_GENERIC = -149;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
similarity index 63%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
index d7eecbb..d513c15 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -31,8 +31,38 @@
 // 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.voice;
+package android.hardware.gnss;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IGnssNavigationMessageCallback {
+  void gnssNavigationMessageCb(in android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage message);
+  @VintfStability
+  parcelable GnssNavigationMessage {
+    int svid;
+    android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage.GnssNavigationMessageType type;
+    int status;
+    int messageId;
+    int submessageId;
+    byte[] data;
+    const int STATUS_PARITY_PASSED = 1;
+    const int STATUS_PARITY_REBUILT = 2;
+    const int STATUS_UNKNOWN = 0;
+    @Backing(type="int") @VintfStability
+    enum GnssNavigationMessageType {
+      UNKNOWN = 0,
+      GPS_L1CA = 257,
+      GPS_L2CNAV = 258,
+      GPS_L5CNAV = 259,
+      SBS = 513,
+      GPS_CNAV2 = 260,
+      GLO_L1CA = 769,
+      QZS_L1CA = 1025,
+      BDS_D1 = 1281,
+      BDS_D2 = 1282,
+      BDS_CNAV1 = 1283,
+      BDS_CNAV2 = 1284,
+      GAL_I = 1537,
+      GAL_F = 1538,
+      IRN_L5CA = 1793,
+    }
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
index 6eadbb7..196e9b9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.gnss;
+@VintfStability
+interface IGnssNavigationMessageInterface {
+  void setCallback(in android.hardware.gnss.IGnssNavigationMessageCallback callback);
+  void close();
 }
diff --git a/gnss/aidl/android/hardware/gnss/GnssLocation.aidl b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
new file mode 100644
index 0000000..25aea4d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
@@ -0,0 +1,91 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.ElapsedRealtime;
+
+/** Represents a location. */
+@VintfStability
+parcelable GnssLocation {
+    /** Bit mask to indicate GnssLocation has valid latitude and longitude. */
+    const int HAS_LAT_LONG = 0x0001;
+    /** Bit mask to indicate GnssLocation has valid altitude. */
+    const int HAS_ALTITUDE = 0x0002;
+    /** Bit mask to indicate GnssLocation has valid speed. */
+    const int HAS_SPEED = 0x0004;
+    /** Bit mask to indicate GnssLocation has valid bearing. */
+    const int HAS_BEARING = 0x0008;
+    /** Bit mask to indicate GnssLocation has valid horizontal accuracy. */
+    const int HAS_HORIZONTAL_ACCURACY = 0x0010;
+    /** Bit mask to indicate GnssLocation has valid vertical accuracy. */
+    const int HAS_VERTICAL_ACCURACY = 0x0020;
+    /** Bit mask to indicate GnssLocation has valid speed accuracy. */
+    const int HAS_SPEED_ACCURACY = 0x0040;
+    /** Bit mask to indicate GnssLocation has valid bearing accuracy. */
+    const int HAS_BEARING_ACCURACY = 0x0080;
+
+    /** A bit field of flags indicating the validity of the fields in this GnssLocation. */
+    int gnssLocationFlags;
+
+    /** Represents latitude in degrees. */
+    double latitudeDegrees;
+
+    /** Represents longitude in degrees. */
+    double longitudeDegrees;
+
+    /** Represents altitude in meters above the WGS 84 reference ellipsoid. */
+    double altitudeMeters;
+
+    /** Represents speed in meters per second. */
+    double speedMetersPerSec;
+
+    /** Represents heading in degrees. */
+    double bearingDegrees;
+
+    /**
+     * Represents expected horizontal position accuracy, radial, in meters (68% confidence).
+     */
+    double horizontalAccuracyMeters;
+
+    /**
+     * Represents expected vertical position accuracy in meters (68% confidence).
+     */
+    double verticalAccuracyMeters;
+
+    /**
+     * Represents expected speed accuracy in meter per seconds (68% confidence).
+     */
+    double speedAccuracyMetersPerSecond;
+
+    /**
+     * Represents expected bearing accuracy in degrees (68% confidence).
+     */
+    double bearingAccuracyDegrees;
+
+    /** Timestamp for the location fix in milliseconds since January 1, 1970. */
+    long timestampMillis;
+
+    /**
+     * Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
+     * clock.
+     *
+     * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
+     * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
+     * needs to be estimated by syncing the notion of time via PTP or some other mechanism.
+     */
+    ElapsedRealtime elapsedRealtime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
new file mode 100644
index 0000000..3e256e2
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -0,0 +1,79 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.IAGnssCallback;
+import android.hardware.gnss.IAGnssCallback.AGnssType;
+
+/** Extended interface for Assisted GNSS support. */
+@VintfStability
+interface IAGnss {
+    /** Access point name IP type */
+    @VintfStability
+    @Backing(type="int")
+    enum ApnIpType {
+        INVALID = 0,
+        IPV4 = 1,
+        IPV6 = 2,
+        IPV4V6 = 3,
+    }
+
+    /**
+     * Opens the AGNSS interface and provides the callback routines to the
+     * implementation of this interface.
+     *
+     * If setCallback is not called, this interface will not respond to any
+     * other method calls.
+     *
+     * @param callback Handle to the AGNSS status callback interface.
+     */
+    void setCallback(in IAGnssCallback callback);
+
+    /**
+     * Notifies that the AGNSS data connection has been closed.
+     */
+    void dataConnClosed();
+
+    /**
+     * Notifies that a data connection is not available for AGNSS.
+     */
+    void dataConnFailed();
+
+    /**
+     * Sets the hostname and port for the AGNSS server.
+     *
+     * @param type Specifies if SUPL or C2K.
+     * @param hostname Hostname of the AGNSS server.
+     * @param port Port number associated with the server.
+     */
+    void setServer(in AGnssType type, in String hostname, in int port);
+
+    /**
+     * Notifies GNSS that a data connection is available and sets the network handle,
+     * name of the APN, and its IP type to be used for SUPL connections.
+     *
+     * The HAL implementation must use the network handle to set the network for the
+     * SUPL connection sockets using the android_setsocknetwork function. This will ensure
+     * that there is a network path to the SUPL server. The network handle can also be used
+     * to get the IP address of SUPL FQDN using the android_getaddrinfofornetwork() function.
+     *
+     * @param networkHandle Handle representing the network for use with the NDK API.
+     * @param apn Access Point Name (follows regular APN naming convention).
+     * @param apnIpType Specifies IP type of APN.
+     */
+    void dataConnOpen(in long networkHandle, in String apn, in ApnIpType apnIpType);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
new file mode 100644
index 0000000..7c25937
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.gnss;
+
+/** Callback structure for the AGNSS interface. */
+@VintfStability
+interface IAGnssCallback {
+    /** AGNSS service type */
+    @VintfStability
+    @Backing(type="int")
+    enum AGnssType {
+        SUPL = 1,
+        C2K = 2,
+        SUPL_EIMS = 3,
+        SUPL_IMS = 4,
+    }
+
+    /** AGNSS status value */
+    @VintfStability
+    @Backing(type="int")
+    enum AGnssStatusValue {
+        /** GNSS requests data connection for AGNSS. */
+        REQUEST_AGNSS_DATA_CONN = 1,
+
+        /** GNSS releases the AGNSS data connection. */
+        RELEASE_AGNSS_DATA_CONN = 2,
+
+        /** AGNSS data connection initiated */
+        AGNSS_DATA_CONNECTED = 3,
+
+        /** AGNSS data connection completed */
+        AGNSS_DATA_CONN_DONE = 4,
+
+        /** AGNSS data connection failed */
+        AGNSS_DATA_CONN_FAILED = 5,
+    }
+
+    /**
+     * Callback with AGNSS status information.
+     *
+     * The GNSS HAL implementation must use this method to request the framework to setup
+     * network connection for the specified AGNSS service and to update the connection
+     * status so that the framework can release the resources.
+     *
+     * @param type Type of AGNSS service.
+     * @parama status Status of the data connection.
+     */
+    void agnssStatusCb(in AGnssType type, in AGnssStatusValue status);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index f99b512..91403ca 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,9 +16,13 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.IAGnss;
+import android.hardware.gnss.IGnssBatching;
 import android.hardware.gnss.IGnssCallback;
 import android.hardware.gnss.IGnssConfiguration;
+import android.hardware.gnss.IGnssGeofence;
 import android.hardware.gnss.IGnssMeasurementInterface;
+import android.hardware.gnss.IGnssNavigationMessageInterface;
 import android.hardware.gnss.IGnssPowerIndication;
 import android.hardware.gnss.IGnssPsds;
 
@@ -27,9 +31,8 @@
  */
 @VintfStability
 interface IGnss {
-
     /**
-     * All GNSS Binder calls may return a ServiceSpecificException with the following error
+     * All GNSS binder calls may return a ServiceSpecificException with the following error
      * codes.
      */
     const int ERROR_INVALID_ARGUMENT = 1;
@@ -73,27 +76,25 @@
     /**
      * This method returns the IGnssPsds interface.
      *
-     * This method must return non-null.
-     *
-     * @return Handle to the IGnssPsds interface.
+     * @return The IGnssPsds interface.
      */
-    IGnssPsds getExtensionPsds();
+    @nullable IGnssPsds getExtensionPsds();
 
     /**
      * This method returns the IGnssConfiguration interface.
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssConfiguration interface.
+     * @return The IGnssConfiguration interface.
      */
     IGnssConfiguration getExtensionGnssConfiguration();
 
     /**
-     * This methods returns the IGnssMeasurementInterface interface.
+     * This method returns the IGnssMeasurementInterface interface.
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssMeasurementInterface interface.
+     * @return The IGnssMeasurementInterface interface.
      */
     IGnssMeasurementInterface getExtensionGnssMeasurement();
 
@@ -102,7 +103,35 @@
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssPowerIndication interface.
+     * @return The IGnssPowerIndication interface.
      */
     IGnssPowerIndication getExtensionGnssPowerIndication();
+
+    /**
+     * This method returns the IGnssBatching interface.
+     *
+     * @return The IGnssBatching interface.
+     */
+    @nullable IGnssBatching getExtensionGnssBatching();
+
+    /**
+     * This method returns the IGnssGeofence interface.
+     *
+     * @return The IGnssGeofence interface.
+     */
+    @nullable IGnssGeofence getExtensionGnssGeofence();
+
+    /**
+     * This method returns the IGnssNavigationMessageInterface.
+     *
+     * @return The IGnssNavigationMessageInterface.
+     */
+    @nullable IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+
+    /**
+     * This method returns the IAGnss interface.
+     *
+     * @return The IAGnss interface.
+     */
+    IAGnss getExtensionAGnss();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
new file mode 100644
index 0000000..0d48ee1
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
@@ -0,0 +1,116 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.IGnssBatchingCallback;
+
+/**
+ * Extended interface for GNSS Batching support.
+ *
+ * If this interface is supported, this batching request must be able to run in parallel with, or
+ * without, non-batched location requested by the IGnss start() & stop() - i.e. both requests must
+ * be handled independently, and not interfere with each other.
+ *
+ * For example, if a 1Hz continuous output is underway on the IGnssCallback, due to an IGnss start()
+ * operation, and then a IGnssBatching start() is called for a location every 10 seconds, the newly
+ * added batching request must not disrupt the 1Hz continuous location output on the IGnssCallback.
+ *
+ * As with GNSS Location outputs, source of location must be GNSS satellite measurements, optionally
+ * using interial and baro sensors to improve relative motion filtering. No additional absolute
+ * positioning information, such as WiFi derived location, may be mixed with the GNSS information.
+ */
+@VintfStability
+interface IGnssBatching {
+    /**
+     * Bit mask indicating batching supports wake up and flush when FIFO is full.
+     *
+     * If this flag is set, the hardware implementation must wake up the application processor when
+     * the FIFO is full, and call IGnssBatchingCallback to return the locations.
+     *
+     * If the flag is not set, the hardware implementation must drop the oldest data when the FIFO
+     * is full.
+     */
+    const int WAKEUP_ON_FIFO_FULL = 0x01;
+
+    /**
+     * Open the interface and provides the callback routines to the implementation of this
+     * interface.
+     *
+     * @param callback Callback interface for IGnssBatching.
+     */
+    void init(in IGnssBatchingCallback callback);
+
+    /**
+     * Return the batch size (in number of GnssLocation objects) available in this hardware
+     * implementation.
+     *
+     * If the available size is variable, for example, based on other operations consuming memory,
+     * this is the minimum size guaranteed to be available for batching operations.
+     *
+     * This may, for example, be used by the client, to decide on the batching interval and whether
+     * the AP should be woken up or not.
+     *
+     * @return the number of location objects supported per batch
+     */
+    int getBatchSize();
+
+    /**
+     * Start batching locations. This API is primarily used when the AP is asleep and the device can
+     * batch locations in the hardware.
+     *
+     * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+     * location.
+     *
+     * When the buffer is full and WAKEUP_ON_FIFO_FULL is used, IGnssBatchingCallback must be called
+     * to return the locations.
+     *
+     * When the buffer is full and WAKEUP_ON_FIFO_FULL is not set, the oldest location object is
+     * dropped. In this case the AP must not be woken up. The AP would then generally be responsible
+     * for using flushBatchedLocation to explicitly ask for the location as needed, to avoid it
+     * being dropped.
+     *
+     * @param periodNanos  Time interval between samples in the location batch, in nanoseconds
+     * @param flags  A bitfield of flags (WAKEUP_ON_FIFO_FULL) indicating the batching behavior
+     */
+    void start(in long periodNanos, in int flags);
+
+    /**
+     * Retrieve all batched locations currently stored.
+     *
+     * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+     * location.
+     *
+     * IGnssBatchingCallback must be called in response, even if there are no locations to flush
+     * (in which case the Location vector must be empty).
+     *
+     * Subsequent calls to flush must not return any of the locations returned in this call.
+     */
+    void flush();
+
+    /**
+     * Stop batching.
+     */
+    void stop();
+
+    /**
+     * Closes the interface. If any batch operations are in progress, they must be stopped.  If any
+     * locations are in the hardware batch, they must be deleted (and not sent via callback.)
+     *
+     * init() may be called again, after this, if the interface is to be restored
+     */
+    void cleanup();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
new file mode 100644
index 0000000..b1bfc57
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.GnssLocation;
+
+/** The callback interface to report batched GNSS locations from the HAL. */
+@VintfStability
+interface IGnssBatchingCallback {
+    /**
+     * Called when a batch of locations is output, by various means, including
+     * a flush request, as well as the buffer becoming full (if appropriate option
+     * is set.)
+     *
+     * All locations returned by this callback must be cleared from the hardware
+     * buffer, such the sequential calls of this callback do not return any
+     * redundant locations.  (Same lat/lon, at a new time, is acceptable.)
+     *
+     * @param locations A list of GNSS Locations
+     */
+    void gnssLocationBatchCb(in GnssLocation[] locations);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..bb4ff93
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.IGnssGeofenceCallback;
+
+/** Extended interface for GNSS Geofence support. */
+@VintfStability
+interface IGnssGeofence {
+    /**
+     * Opens the geofence interface and provides the callback routines to the HAL.
+     *
+     * @param callback Handle to the IGnssGeofenceCallback interface.
+     */
+    void setCallback(in IGnssGeofenceCallback callback);
+
+    /**
+     * Add a geofence area. This api currently supports circular geofences.
+     *
+     * @param geofenceId The id for the geofence. If a geofence with this id already exists, an
+     * error value (ERROR_ID_EXISTS) must be returned.
+     * @param latitudeDegrees The latitude(in degrees) for the geofence lastTransition.
+     * @param longitudeDegrees The longitude(in degrees) for the geofence lastTransition.
+     * @param radiusMeters The radius(in meters) for the geofence lastTransition.
+     * @param lastTransition The current state of the geofence. It can be one of the transition
+     * states (ENTERED, EXITED, UNCERTAIN) as defined in IGnssGeofenceCallback. For example, if
+     * the system already knows that the user is inside the geofence, this will be set to ENTERED.
+     * In most cases, it will be UNCERTAIN.
+     * @param monitorTransitions A bitfield of ENTERED, EXITED and UNCERTAIN. It represents which
+     * transitions to monitor.
+     * @param notificationResponsivenessMs - Defines the best-effort description of how soon must
+     * the callback be called when the transition associated with the Geofence is triggered. For
+     * instance, if set to 1000 milliseconds with ENTERED, the callback must be called 1000
+     * milliseconds within entering the geofence. This parameter is defined in milliseconds.
+     * NOTE: This is not to be confused with the rate that the GNSS is polled at. It is acceptable
+     * to dynamically vary the rate of sampling the GNSS for power-saving reasons; thus the rate of
+     * sampling may be faster or slower than this.
+     * @param unknownTimerMs - The time limit in millisecondsafter which the UNCERTAIN transition
+     * must be triggered.
+     */
+    void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees,
+            in double radiusMeters, in int lastTransition, in int monitorTransitions,
+            in int notificationResponsivenessMs, in int unknownTimerMs);
+
+    /**
+     * Pause monitoring a particular geofence.
+     *
+     * @param geofenceId The id for the geofence.
+     */
+    void pauseGeofence(in int geofenceId);
+
+    /**
+     * Resume monitoring a particular geofence.
+     *
+     * @param geofenceId - The id for the geofence.
+     * @param monitorTransitions Specifies which transitions to monitor. It can be a bitwise OR of
+     * ENTERED, EXITED and UNCERTAIN. This supersedes the value associated provided in the
+     * addGeofence call.
+     */
+    void resumeGeofence(in int geofenceId, in int monitorTransitions);
+
+    /**
+     * Remove a geofence area. After the function returns, no notifications must be sent.
+     *
+     * @param geofenceId The id of the geofence.
+     */
+    void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..c176965
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -0,0 +1,184 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.GnssLocation;
+
+/**
+ * The callback interface to report GNSS geofence events from the HAL.
+ *
+ * There are 3 states associated with a Geofence: Inside, Outside, Unknown.
+ * There are 3 transitions: ENTERED, EXITED, UNCERTAIN.
+ *
+ * An example state diagram with confidence level: 95% and Unknown time limit
+ * set as 30 secs is shown below. (confidence level and Unknown time limit are
+ * explained latter).
+ *                         ____________________________
+ *                        |       Unknown (30 secs)   |
+ *                         """"""""""""""""""""""""""""
+ *                            ^ |                  |  ^
+ *                   UNCERTAIN| |ENTERED     EXITED|  |UNCERTAIN
+ *                            | v                  v  |
+ *                        ________    EXITED     _________
+ *                       | Inside | -----------> | Outside |
+ *                       |        | <----------- |         |
+ *                        """"""""    ENTERED    """""""""
+ *
+ * Inside state: We are 95% confident that the user is inside the geofence.
+ * Outside state: We are 95% confident that the user is outside the geofence
+ * Unknown state: Rest of the time.
+ *
+ * The Unknown state is better explained with an example:
+ *
+ *                            __________
+ *                           |         c|
+ *                           |  ___     |    _______
+ *                           |  |a|     |   |   b   |
+ *                           |  """     |    """""""
+ *                           |          |
+ *                            """"""""""
+ * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy
+ * circle reported by the GNSS subsystem. Now with regard to "b", the system is
+ * confident that the user is outside. But with regard to "a" is not confident
+ * whether it is inside or outside the geofence. If the accuracy remains the
+ * same for a sufficient period of time, the UNCERTAIN transition must be
+ * triggered with the state set to Unknown. If the accuracy improves later, an
+ * appropriate transition must be triggered.  This "sufficient period of time"
+ * is defined by the parameter in the addGeofenceArea API.
+ * In other words, Unknown state can be interpreted as a state in which the
+ * GNSS subsystem isn't confident enough that the user is either inside or
+ * outside the Geofence. It moves to Unknown state only after the expiry of the
+ * timeout.
+ *
+ * The geofence callback needs to be triggered for the ENTERED and EXITED
+ * transitions, when the GNSS system is confident that the user has entered
+ * (Inside state) or exited (Outside state) the Geofence. An implementation
+ * which uses a value of 95% as the confidence is recommended. The callback
+ * must be triggered only for the transitions requested by the
+ * addGeofenceArea method.
+ *
+ * Even though the diagram and explanation talks about states and transitions,
+ * the callee is only interested in the transitions. The states are mentioned
+ * here for illustrative purposes.
+ *
+ * Startup Scenario: When the device boots up, if an application adds geofences,
+ * and then we get an accurate GNSS location fix, it needs to trigger the
+ * appropriate (ENTERED or EXITED) transition for every Geofence it knows about.
+ * By default, all the Geofences will be in the Unknown state.
+ *
+ * When the GNSS system is unavailable, gnssGeofenceStatusCb must be
+ * called to inform the upper layers of the same. Similarly, when it becomes
+ * available the callback must be called. This is a global state while the
+ * UNKNOWN transition described above is per geofence.
+ *
+ * An important aspect to note is that users of this API (framework), will use
+ * other subsystems like wifi, sensors, cell to handle Unknown case and
+ * hopefully provide a definitive state transition to the third party
+ * application. GNSS Geofence will just be a signal indicating what the GNSS
+ * subsystem knows about the Geofence.
+ */
+@VintfStability
+interface IGnssGeofenceCallback {
+    // Geofence transition status
+    const int ENTERED = 1 << 0;
+    const int EXITED = 1 << 1;
+    const int UNCERTAIN = 1 << 2;
+
+    // Geofence availability status
+    const int UNAVAILABLE = 1 << 0;
+    const int AVAILABLE = 1 << 1;
+
+    // Geofence operation status
+    const int OPERATION_SUCCESS = 0;
+    const int ERROR_TOO_MANY_GEOFENCES = -100;
+    const int ERROR_ID_EXISTS = -101;
+    const int ERROR_ID_UNKNOWN = -102;
+    const int ERROR_INVALID_TRANSITION = -103;
+    const int ERROR_GENERIC = -149;
+
+    /**
+     * The callback associated with the geofence transition.
+     *
+     * The callback must only be called when the caller is interested in that particular transition.
+     * For instance, if the caller is interested only in ENTERED transition, then the callback must
+     * not be called with the EXITED transition.
+     *
+     * IMPORTANT: If a transition is triggered resulting in this callback, the GNSS subsystem will
+     * wake up the application processor, if it is in suspend state.
+     *
+     * @param geofenceId The id associated with the addGeofenceArea.
+     * @param location The current GNSS location.
+     * @param transition Can be one of ENTERED, EXITED or UNCERTAIN.
+     * @param timestamp Timestamp (in UTC milliseconds) when the transition was detected.
+     */
+    void gnssGeofenceTransitionCb(in int geofenceId, in GnssLocation location, in int transition,
+            in long timestampMillis);
+
+    /**
+     * The callback associated with the availability of the GNSS system for geofencing monitoring.
+     * If the GNSS system determines that it cannot monitor geofences because of lack of reliability
+     * or unavailability of the GNSS signals, it will call this callback with UNAVAILABLE parameter.
+     *
+     * @param status - UNAVAILABLE or AVAILABLE.
+     * @param lastLocation - Last known location.
+     */
+    void gnssGeofenceStatusCb(in int availability, in GnssLocation lastLocation);
+
+    /**
+     * The callback associated with the addGeofence call.
+     *
+     * @param geofenceId Id of the geofence.
+     * @param status Returns OPERATION_SUCCESS if the geofence add was successful,
+     *               returns ERROR_TOO_MANY_GEOFENCES if the geofence limit has been reached,
+     *               returns ERROR_ID_EXISTS if geofence with id already exists,
+     *               returns ERROR_INVALID_TRANSITION if the monitorTransition contains an invalid
+     *               transition, and
+     *               returns ERROR_GENERIC for other errors.
+     */
+    void gnssGeofenceAddCb(in int geofenceId, in int status);
+
+    /**
+     * The callback associated with the removeGeofence call.
+     *
+     * @param geofenceId Id of the geofence.
+     * @param status Returns OPERATION_SUCCESS if successful,
+     *               returns ERROR_ID_UNKNOWN for invalid id and
+     *               returns ERROR_GENERIC for others.
+     */
+    void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+
+    /**
+     * The callback associated with the pauseGeofence call.
+     *
+     * @param geofenceId Id of the geofence.
+     * @param status Returns OPERATION_SUCCESS if success,
+     *               returns ERROR_ID_UNKNOWN for invalid id,
+     *               returns ERROR_INVALID_TRANSITION when monitorTransitions is invalid, and
+     *               returns ERROR_GENERIC for other err errors.
+     */
+    void gnssGeofencePauseCb(in int geofenceId, in int status);
+
+    /**
+     * The callback associated with the resumeGeofence call.
+     *
+     * @param geofenceId - Id of the geofence.
+     * @param status Returns OPERATION_SUCCESS if successful,
+     *               returns ERROR_ID_UNKNOWN for invalid id, and
+     *               returns ERROR_GENERIC for others.
+     */
+    void gnssGeofenceResumeCb(in int geofenceId, in int status);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..0fdfaf8
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,240 @@
+/*
+ * 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.gnss;
+
+/** Represents a GNSS navigation message (or a fragment of it). */
+@VintfStability
+interface IGnssNavigationMessageCallback {
+    /**
+     * Represents a reading of GNSS measurements. For devices launched in Android Q or newer, it is
+     * mandatory that these be provided, on request, when the GNSS receiver is searching/tracking
+     * signals.
+     *
+     * - Reporting of GNSS constellation measurements is mandatory.
+     * - Reporting of all tracked constellations are encouraged.
+     */
+    @VintfStability
+    parcelable GnssNavigationMessage {
+        /**
+         * Status of Navigation Message
+         *
+         * When a message is received properly without any parity error in its
+         * navigation words, the status must be set to PARITY_PASSED.
+         *
+         * If a message is received with words that failed a parity check, but the GNSS
+         * receiver has corrected those words, the status must be set to PARITY_REBUILT.
+         *
+         * Do not send any navigation message that contains words with parity errors
+         * that cannot be corrected.
+         */
+        const int STATUS_PARITY_PASSED = (1 << 0);
+        const int STATUS_PARITY_REBUILT = (1 << 1);
+        const int STATUS_UNKNOWN = 0;
+
+        /**
+         * Enumeration of available values to indicate the GNSS Navigation message
+         * types.
+         *
+         * For convenience, first byte is the GnssConstellationType on which that signal
+         * is typically transmitted.
+         */
+        @VintfStability
+        @Backing(type="int")
+        enum GnssNavigationMessageType {
+            UNKNOWN = 0,
+
+            /** GPS L1 C/A message contained in the structure.  */
+            GPS_L1CA = 0x0101,
+
+            /** GPS L2-CNAV message contained in the structure. */
+            GPS_L2CNAV = 0x0102,
+
+            /** GPS L5-CNAV message contained in the structure. */
+            GPS_L5CNAV = 0x0103,
+
+            /* SBAS message contained in the structure. */
+            SBS = 0x0201,
+
+            /** GPS CNAV-2 message contained in the structure. */
+            GPS_CNAV2 = 0x0104,
+
+            /** Glonass L1 CA message contained in the structure. */
+            GLO_L1CA = 0x0301,
+
+            /** QZSS L1 C/A message contained in the structure. */
+            QZS_L1CA = 0x0401,
+
+            /** Beidou D1 message contained in the structure. */
+            BDS_D1 = 0x0501,
+
+            /** Beidou D2 message contained in the structure. */
+            BDS_D2 = 0x0502,
+
+            /** Beidou CNAV1 message contained in the structure. */
+            BDS_CNAV1 = 0x0503,
+
+            /** Beidou CNAV2 message contained in the structure. */
+            BDS_CNAV2 = 0x0504,
+
+            /** Galileo I/NAV message contained in the structure. */
+            GAL_I = 0x0601,
+
+            /** Galileo F/NAV message contained in the structure. */
+            GAL_F = 0x0602,
+
+            /** IRNSS L5 C/A message contained in the structure. */
+            IRN_L5CA = 0x0701,
+        }
+
+        /**
+         * Satellite vehicle ID number, as defined in GnssSvInfo::svid
+         *
+         * This is a mandatory value.
+         */
+        int svid;
+
+        /**
+         * The type of message contained in the structure.
+         *
+         * This is a mandatory value.
+         */
+        GnssNavigationMessageType type;
+
+        /**
+         * The status of the received navigation message.
+         *
+         * It is a bitfield of constants with prefix "STATUS_" defined in this structure.
+         *
+         * No need to send any navigation message that contains words with parity
+         * errors that cannot be corrected.
+         */
+        int status;
+
+        /**
+         * Message identifier. It provides an index so the complete Navigation
+         * Message can be assembled.
+         *
+         * - For GNSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame
+         *   id' of the navigation message, in the range of 1-25 (Subframe 1, 2, 3
+         *   does not contain a 'frame id' and this value can be set to -1.)
+         *
+         * - For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.
+         *
+         * - For BeiDou D1, this refers to the frame number in the range of 1-24
+         *
+         * - For Beidou D2, this refers to the frame number, in the range of 1-120
+         *
+         * - For Galileo F/NAV nominal frame structure, this refers to the subframe
+         *   number, in the range of 1-12
+         *
+         * - For Galileo I/NAV nominal frame structure, this refers to the subframe
+         *   number in the range of 1-24
+         *
+         * - For SBAS and Beidou CNAV2, this is unused and can be set to -1.
+         *
+         * - For QZSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+         *   navigation message, in the range of 1-25. (Subframe 1, 2, 3 does not contain a 'frame
+         *   id' and this value can be set to -1.)
+         *
+         * - For Beidou CNAV1 this refers to the page type number in the range of 1-63.
+         *
+         * - For IRNSS L5 C/A subframe 3 and 4, this value corresponds to the Message Id of the
+         *   navigation message, in the range of 1-63. (Subframe 1 and 2 does not contain a message
+         *   type id and this value can be set to -1.)
+         */
+        int messageId;
+
+        /**
+         * Sub-message identifier. If required by the message 'type', this value contains a
+         * sub-index within the current message (or frame) that is being transmitted.
+         *
+         * - For GNSS L1 C/A, BeiDou D1 & BeiDou D2, the submessage id corresponds to the subframe
+         *   number of the navigation message, in the range of 1-5.
+         *
+         * - For Glonass L1 C/A, this refers to the String number, in the range from 1-15.
+         *
+         * - For Galileo F/NAV, this refers to the page type in the range 1-6.
+         *
+         * - For Galileo I/NAV, this refers to the word type in the range 0-10+. A value of 0 is
+         *   only allowed if the Satellite is transmiting a Spare Word.
+         *
+         * - For Galileo in particular, the type information embedded within the data bits may be
+         *   even more useful in interpretation, than the nominal page and word types provided in
+         *   this field.
+         *
+         * - For SBAS, the submessage id corresponds to the message type, in the range 1-63.
+         *
+         * - For Beidou CNAV1, the submessage id corresponds to the subframe number of the
+         *   navigation message, in the range of 1-3.
+         *
+         * - For Beidou CNAV2, the submessage id corresponds to the message type, in the range 1-63.
+         *
+         * - For IRNSS L5 C/A, the submessage id corresponds to the subframe number of the
+         *   navigation message, in the range of 1-4.
+         */
+        int submessageId;
+
+        /**
+         * The data of the reported GNSS message. The bytes (or words) are specified
+         * using big endian format (MSB first).
+         *
+         * - For GNSS L1 C/A, Beidou D1 & Beidou D2, each subframe contains 10 30-bit
+         *   words. Each word (30 bits) must fit into the last 30 bits in a
+         *   4-byte word (skip B31 and B32), with MSB first, for a total of 40
+         *   bytes, covering a time period of 6, 6, and 0.6 seconds, respectively.
+         *   The standard followed is 1995 SPS Signal specification.
+         *
+         * - For Glonass L1 C/A, each string contains 85 data bits, including the
+         *   checksum.  These bits must fit into 11 bytes, with MSB first (skip
+         *   B86-B88), covering a time period of 2 seconds.
+         *   The standard followed is Glonass Interface Control Document Edition 5.1.
+         *
+         * - For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols
+         *   excluded). Each word must fit into 30-bytes, with MSB first (skip
+         *   B239, B240), covering a time period of 10 seconds. The standard
+         *   followed is European GNSS(Galileo) Signal in Space Interface
+         *   Control Document Issue 1.2.
+         *
+         * - For Galileo I/NAV, each page contains 2 page parts, even and odd, with
+         *   a total of 2x114 = 228 bits, (sync & tail excluded) that must fit
+         *   into 29 bytes, with MSB first (skip B229-B232). The standard followed
+         *   is same as above.
+         *
+         * - For SBAS, each block consists of 250 data bits, that should be fit into 32 bytes. MSB
+         *   first (skip B251-B256).
+         *
+         * - For Beidou CNAV1, subframe #1 consists of 14 data bits, that should be fit into 2
+         *   bytes. MSB first (skip B15-B16).  subframe #2 consists of 600 bits that should be fit
+         *   into 75 bytes. subframe #3 consists of 264 data bits that should be fit into 33 bytes.
+         *
+         * - For Beidou CNAV2, each subframe consists of 288 data bits, that should be fit into 36
+         *   bytes.
+         *
+         * The data reported here must be the raw data as demodulated by the GNSS receiver, not data
+         * received from an external source (i.e. not from a server download.)
+         */
+        byte[] data;
+    }
+
+    /**
+     * The callback to report an available fragment of a GNSS navigation messages
+     * from the HAL.
+     *
+     * @param message - The GNSS navigation submessage/subframe representation.
+     */
+    void gnssNavigationMessageCb(in GnssNavigationMessage message);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..e2f57c3
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.IGnssNavigationMessageCallback;
+
+/**
+ * Extended interface for GNSS navigation message reporting support.
+ */
+@VintfStability
+interface IGnssNavigationMessageInterface {
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     *
+     * After a successful call to 'setCallback' the HAL must begin to provide updates as
+     * they become available.
+     *
+     * @param callback handle to IGnssNavigationMessageCallack interface.
+     */
+    void setCallback(in IGnssNavigationMessageCallback callback);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     *
+     * After a call to close(), the previously registered callbacks must be
+     * considered invalid by the HAL.
+     *
+     * If close() is invoked without a previous setCallback, this function must perform
+     * no work.
+     */
+    void close();
+}
diff --git a/gnss/aidl/default/AGnss.cpp b/gnss/aidl/default/AGnss.cpp
new file mode 100644
index 0000000..e8d5ef7
--- /dev/null
+++ b/gnss/aidl/default/AGnss.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AGnssAidl"
+
+#include "AGnss.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IAGnssCallback> AGnss::sCallback = nullptr;
+
+ndk::ScopedAStatus AGnss::setCallback(const std::shared_ptr<IAGnssCallback>& callback) {
+    ALOGD("AGnss::setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::setServer(AGnssType type, const std::string& hostname, int port) {
+    ALOGD("AGnss::setServer: type: %s, hostname: %s, port: %d", toString(type).c_str(),
+          hostname.c_str(), port);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::dataConnOpen(int64_t networkHandle, const std::string& apn,
+                                       ApnIpType apnIpType) {
+    ALOGD("AGnss::dataConnOpen: networkHandle:%" PRId64 ", apn: %s, apnIpType %s", networkHandle,
+          apn.c_str(), toString(apnIpType).c_str());
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/AGnss.h b/gnss/aidl/default/AGnss.h
new file mode 100644
index 0000000..cd973e1
--- /dev/null
+++ b/gnss/aidl/default/AGnss.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnAGnss.h>
+
+namespace aidl::android::hardware::gnss {
+
+using AGnssType = IAGnssCallback::AGnssType;
+
+struct AGnss : public BnAGnss {
+  public:
+    ndk::ScopedAStatus setCallback(const std::shared_ptr<IAGnssCallback>& callback) override;
+    ndk::ScopedAStatus dataConnClosed() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus dataConnFailed() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus setServer(AGnssType type, const std::string& hostname, int port) override;
+    ndk::ScopedAStatus dataConnOpen(int64_t networkHandle, const std::string& apn,
+                                    ApnIpType apnIpType) override;
+
+  private:
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+    // Guarded by mMutex
+    static std::shared_ptr<IAGnssCallback> sCallback;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index c028dd7..1236714 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -52,11 +52,15 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
     srcs: [
+        "AGnss.cpp",
         "Gnss.cpp",
+        "GnssBatching.cpp",
+        "GnssGeofence.cpp",
         "GnssHidlHal.cpp",
+        "GnssNavigationMessageInterface.cpp",
         "GnssPowerIndication.cpp",
         "GnssPsds.cpp",
         "GnssConfiguration.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 6061eec..0e3cdd3 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,8 +18,12 @@
 
 #include "Gnss.h"
 #include <log/log.h>
+#include "AGnss.h"
+#include "GnssBatching.h"
 #include "GnssConfiguration.h"
+#include "GnssGeofence.h"
 #include "GnssMeasurementInterface.h"
+#include "GnssNavigationMessageInterface.h"
 #include "GnssPsds.h"
 
 namespace aidl::android::hardware::gnss {
@@ -53,6 +57,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
+    ALOGD("Gnss::getExtensionAGnss");
+    *iAGnss = SharedRefBase::make<AGnss>();
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
     ALOGD("Gnss::getExtensionPsds");
     *iGnssPsds = SharedRefBase::make<GnssPsds>();
@@ -88,4 +98,26 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+    ALOGD("Gnss::getExtensionGnssBatching");
+
+    *iGnssBatching = SharedRefBase::make<GnssBatching>();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+    ALOGD("Gnss::getExtensionGnssGeofence");
+
+    *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+        std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
+    ALOGD("Gnss::getExtensionGnssNavigationMessage");
+
+    *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 76ebe4d..4feb781 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -16,7 +16,9 @@
 
 #pragma once
 
+#include <aidl/android/hardware/gnss/BnAGnss.h>
 #include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
@@ -37,6 +39,13 @@
             std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
     ndk::ScopedAStatus getExtensionGnssMeasurement(
             std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
+    ndk::ScopedAStatus getExtensionGnssBatching(
+            std::shared_ptr<IGnssBatching>* iGnssBatching) override;
+    ndk::ScopedAStatus getExtensionGnssGeofence(
+            std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
+    ndk::ScopedAStatus getExtensionGnssNavigationMessage(
+            std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) override;
+    ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssBatching.cpp b/gnss/aidl/default/GnssBatching.cpp
new file mode 100644
index 0000000..b8be5e5
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssBatchingAidl"
+
+#include "GnssBatching.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+
+constexpr int BATCH_SIZE = 10;
+
+std::shared_ptr<IGnssBatchingCallback> GnssBatching::sCallback = nullptr;
+
+GnssBatching::GnssBatching()
+    : mMinIntervalMs(1000),
+      mWakeUpOnFifoFull(false),
+      mBatchedLocations(std::vector<GnssLocation>()) {}
+GnssBatching::~GnssBatching() {
+    cleanup();
+}
+
+ndk::ScopedAStatus GnssBatching::init(const std::shared_ptr<IGnssBatchingCallback>& callback) {
+    ALOGD("init");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::getBatchSize(int* size) {
+    ALOGD("getBatchingSize");
+    *size = BATCH_SIZE;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::start(int64_t periodNanos, int flags) {
+    ALOGD("start: periodNanos=%" PRId64 ", flags=%d", periodNanos, flags);
+    if (mIsActive) {
+        ALOGW("Gnss has started. Restarting...");
+        stop();
+    }
+
+    mWakeUpOnFifoFull = (flags & IGnssBatching::WAKEUP_ON_FIFO_FULL) ? true : false;
+    // mMinIntervalMs is not smaller than 1 sec
+    periodNanos = (periodNanos < 1e9) ? 1e9 : periodNanos;
+    mMinIntervalMs = periodNanos / 1e6;
+
+    mIsActive = true;
+    mThread = std::thread([this]() {
+        while (mIsActive == true) {
+            const auto location = common::Utils::getMockLocation();
+            this->batchLocation(location);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+        }
+    });
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::flush() {
+    ALOGD("flush");
+    std::vector<GnssLocation> copy = std::vector<GnssLocation>(mBatchedLocations);
+    ndk::ScopedAStatus status;
+    if (sCallback != nullptr) {
+        sCallback->gnssLocationBatchCb(copy);
+        status = ndk::ScopedAStatus::ok();
+    } else {
+        ALOGE("GnssBatchingCallback is null. flush() failed.");
+        status = ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_GENERIC);
+    }
+    mBatchedLocations.clear();
+    return status;
+}
+
+ndk::ScopedAStatus GnssBatching::stop() {
+    ALOGD("stop");
+    // Do not call flush() at stop()
+    mIsActive = false;
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::cleanup() {
+    ALOGD("cleanup");
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (mIsActive) {
+        stop();
+    }
+    flush();
+
+    sCallback = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+void GnssBatching::batchLocation(const GnssLocation& location) {
+    if (mBatchedLocations.size() > BATCH_SIZE) {
+        mBatchedLocations.erase(mBatchedLocations.begin());
+    }
+    mBatchedLocations.push_back(location);
+    if (mWakeUpOnFifoFull && mBatchedLocations.size() == BATCH_SIZE) {
+        flush();
+    }
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssBatching.h b/gnss/aidl/default/GnssBatching.h
new file mode 100644
index 0000000..7cd6e85
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssBatching : public BnGnssBatching {
+  public:
+    GnssBatching();
+    ~GnssBatching();
+    ndk::ScopedAStatus init(const std::shared_ptr<IGnssBatchingCallback>& callback) override;
+    ndk::ScopedAStatus getBatchSize(int* size) override;
+    ndk::ScopedAStatus start(int64_t periodNanos, int flags) override;
+    ndk::ScopedAStatus flush() override;
+    ndk::ScopedAStatus stop() override;
+    ndk::ScopedAStatus cleanup() override;
+
+  private:
+    void batchLocation(const GnssLocation&);
+
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssBatchingCallback> sCallback;
+
+    std::thread mThread;
+    std::atomic<bool> mIsActive;
+    std::atomic<long> mMinIntervalMs;
+    std::atomic<bool> mWakeUpOnFifoFull;
+
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+
+    std::vector<GnssLocation> mBatchedLocations;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssGeofence.cpp b/gnss/aidl/default/GnssGeofence.cpp
new file mode 100644
index 0000000..eda33cc
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssGeofenceAidl"
+
+#include "GnssGeofence.h"
+#include <aidl/android/hardware/gnss/BnGnssGeofence.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IGnssGeofenceCallback> GnssGeofence::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssGeofence::setCallback(
+        const std::shared_ptr<IGnssGeofenceCallback>& callback) {
+    ALOGD("setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::addGeofence(int geofenceId, double latitudeDegrees,
+                                             double longitudeDegrees, double radiusMeters,
+                                             int lastTransition, int monitorTransitions,
+                                             int notificationResponsivenessMs, int unknownTimerMs) {
+    ALOGD("addGeofence. geofenceId=%d, lat=%lf, lng=%lf, rad=%lf, lastTransition=%d, "
+          "monitorTransitions=%d, notificationResponsivenessMs=%d, unknownTimerMs=%d",
+          geofenceId, latitudeDegrees, longitudeDegrees, radiusMeters, lastTransition,
+          monitorTransitions, notificationResponsivenessMs, unknownTimerMs);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::pauseGeofence(int geofenceId) {
+    ALOGD("pauseGeofence. id=%d", geofenceId);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::resumeGeofence(int geofenceId, int monitorTransitions) {
+    ALOGD("resumeGeofence. id=%d, monitorTransitions=%d", geofenceId, monitorTransitions);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::removeGeofence(int geofenceId) {
+    ALOGD("removeGeofence. id=%d", geofenceId);
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssGeofence.h b/gnss/aidl/default/GnssGeofence.h
new file mode 100644
index 0000000..313e832
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssGeofence.h>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssGeofence : public BnGnssGeofence {
+  public:
+    ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssGeofenceCallback>& callback) override;
+    ndk::ScopedAStatus addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees,
+                                   double radiusMeters, int lastTransition, int monitorTransitions,
+                                   int notificationResponsivenessMs, int unknownTimerMs) override;
+    ndk::ScopedAStatus pauseGeofence(int geofenceId) override;
+    ndk::ScopedAStatus resumeGeofence(int geofenceId, int monitorTransitions) override;
+    ndk::ScopedAStatus removeGeofence(int geofenceId) override;
+
+  private:
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssGeofenceCallback> sCallback;
+
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.cpp b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
new file mode 100644
index 0000000..4bc859d
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssNavigationMessageAidl"
+
+#include "GnssNavigationMessageInterface.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+using GnssNavigationMessage = IGnssNavigationMessageCallback::GnssNavigationMessage;
+using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageType;
+
+std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
+
+GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
+
+GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
+    stop();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
+        const std::shared_ptr<IGnssNavigationMessageCallback>& callback) {
+    ALOGD("setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    start();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
+    ALOGD("close");
+    stop();
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+void GnssNavigationMessageInterface::start() {
+    ALOGD("start");
+    mIsActive = true;
+    mThread = std::thread([this]() {
+        while (mIsActive == true) {
+            GnssNavigationMessage message = {
+                    .svid = 19,
+                    .type = GnssNavigationMessageType::GPS_L1CA,
+                    .status = GnssNavigationMessage::STATUS_PARITY_PASSED,
+                    .messageId = 2,
+                    .submessageId = 3,
+                    .data = std::vector<uint8_t>(40, 0xF9),
+            };
+            this->reportMessage(message);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+        }
+    });
+    mThread.detach();
+}
+
+void GnssNavigationMessageInterface::stop() {
+    ALOGD("stop");
+    mIsActive = false;
+}
+
+void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage& message) {
+    ALOGD("reportMessage()");
+    std::shared_ptr<IGnssNavigationMessageCallback> callbackCopy;
+    {
+        std::unique_lock<std::mutex> lock(mMutex);
+        if (sCallback == nullptr) {
+            ALOGE("%s: GnssNavigationMessageInterface::sCallback is null.", __func__);
+            return;
+        }
+        callbackCopy = sCallback;
+    }
+    callbackCopy->gnssNavigationMessageCb(message);
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.h b/gnss/aidl/default/GnssNavigationMessageInterface.h
new file mode 100644
index 0000000..600b23a
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssNavigationMessageInterface.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface {
+  public:
+    GnssNavigationMessageInterface();
+    ~GnssNavigationMessageInterface();
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IGnssNavigationMessageCallback>& callback) override;
+    ndk::ScopedAStatus close() override;
+
+  private:
+    void start();
+    void stop();
+    void reportMessage(const IGnssNavigationMessageCallback::GnssNavigationMessage& message);
+
+    std::atomic<long> mMinIntervalMillis;
+    std::atomic<bool> mIsActive;
+    std::thread mThread;
+
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssNavigationMessageCallback> sCallback;
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index 2b06cd2..7449310 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,6 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.gnss</name>
+        <version>2</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/gnss/aidl/vts/AGnssCallbackAidl.cpp
similarity index 65%
rename from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
rename to gnss/aidl/vts/AGnssCallbackAidl.cpp
index 46a9b1a..3327835 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/gnss/aidl/vts/AGnssCallbackAidl.cpp
@@ -14,14 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+#include "AGnssCallbackAidl.h"
+#include <log/log.h>
 
-import android.hardware.radio.voice.CdmaInformationRecord;
-
-@VintfStability
-parcelable CdmaInformationRecords {
-    /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
-     */
-    CdmaInformationRecord[] infoRec;
+android::binder::Status AGnssCallbackAidl::agnssStatusCb(const AGnssType type,
+                                                         const AGnssStatusValue status) {
+    ALOGI("agnssStatusCb type %d status %d", type, status);
+    return android::binder::Status::ok();
 }
diff --git a/gnss/aidl/vts/AGnssCallbackAidl.h b/gnss/aidl/vts/AGnssCallbackAidl.h
new file mode 100644
index 0000000..6173e85
--- /dev/null
+++ b/gnss/aidl/vts/AGnssCallbackAidl.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnAGnssCallback.h>
+
+using AGnssType = android::hardware::gnss::IAGnssCallback::AGnssType;
+using AGnssStatusValue = android::hardware::gnss::IAGnssCallback::AGnssStatusValue;
+
+/** Implementation for IAGnssCallback. */
+class AGnssCallbackAidl : public android::hardware::gnss::BnAGnssCallback {
+  public:
+    AGnssCallbackAidl(){};
+    ~AGnssCallbackAidl(){};
+    android::binder::Status agnssStatusCb(const AGnssType type,
+                                          const AGnssStatusValue status) override;
+};
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 838849d..041d579 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -30,8 +30,12 @@
     srcs: [
         "gnss_hal_test.cpp",
         "gnss_hal_test_cases.cpp",
+        "AGnssCallbackAidl.cpp",
+        "GnssBatchingCallback.cpp",
         "GnssCallbackAidl.cpp",
+        "GnssGeofenceCallback.cpp",
         "GnssMeasurementCallbackAidl.cpp",
+        "GnssNavigationMessageCallback.cpp",
         "GnssPowerIndicationCallback.cpp",
         "VtsHalGnssTargetTest.cpp",
     ],
@@ -43,7 +47,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.gnss-V1-cpp",
+        "android.hardware.gnss-V2-cpp",
         "android.hardware.gnss@common-vts-lib",
     ],
     test_suites: [
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
new file mode 100644
index 0000000..2da3b12
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssBatchingCallback.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+android::binder::Status GnssBatchingCallback::gnssLocationBatchCb(
+        const std::vector<android::hardware::gnss::GnssLocation>& locations) {
+    ALOGI("Batched locations received with size=%d", (int)locations.size());
+    for (const auto& location : locations) {
+        ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+              location.elapsedRealtime.flags, location.elapsedRealtime.timestampNs,
+              location.elapsedRealtime.timeUncertaintyNs);
+    }
+    batched_locations_cbq_.store(locations);
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssBatchingCallback.h b/gnss/aidl/vts/GnssBatchingCallback.h
new file mode 100644
index 0000000..310a134
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssBatchingCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssBatchingCallback. */
+class GnssBatchingCallback : public android::hardware::gnss::BnGnssBatchingCallback {
+  public:
+    GnssBatchingCallback() : batched_locations_cbq_("batched_locations") {}
+    ~GnssBatchingCallback() {}
+
+    android::binder::Status gnssLocationBatchCb(
+            const std::vector<android::hardware::gnss::GnssLocation>& locations) override;
+
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<android::hardware::gnss::GnssLocation>>
+            batched_locations_cbq_;
+    std::vector<android::hardware::gnss::GnssLocation> last_batched_locations_;
+};
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.cpp b/gnss/aidl/vts/GnssGeofenceCallback.cpp
new file mode 100644
index 0000000..b841cb9
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssGeofenceCallback.h"
+#include <log/log.h>
+
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+
+Status GnssGeofenceCallback::gnssGeofenceTransitionCb(int, const GnssLocation&, int, int64_t) {
+    // To implement
+    return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceStatusCb(int, const GnssLocation&) {
+    // To implement
+    return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceAddCb(int, int) {
+    // To implement
+    return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceRemoveCb(int, int) {
+    // To implement
+    return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofencePauseCb(int, int) {
+    // To implement
+    return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceResumeCb(int, int) {
+    // To implement
+    return Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.h b/gnss/aidl/vts/GnssGeofenceCallback.h
new file mode 100644
index 0000000..b105518
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssGeofenceCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssGeofenceCallback. */
+class GnssGeofenceCallback : public android::hardware::gnss::BnGnssGeofenceCallback {
+  public:
+    GnssGeofenceCallback() {}
+    ~GnssGeofenceCallback() {}
+
+    android::binder::Status gnssGeofenceTransitionCb(
+            int geofenceId, const android::hardware::gnss::GnssLocation& location, int transition,
+            int64_t timestampMillis) override;
+    android::binder::Status gnssGeofenceStatusCb(
+            int availability, const android::hardware::gnss::GnssLocation& lastLocation) override;
+    android::binder::Status gnssGeofenceAddCb(int geofenceId, int status) override;
+    android::binder::Status gnssGeofenceRemoveCb(int geofenceId, int status) override;
+    android::binder::Status gnssGeofencePauseCb(int geofenceId, int status) override;
+    android::binder::Status gnssGeofenceResumeCb(int geofenceId, int status) override;
+};
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.cpp b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
new file mode 100644
index 0000000..cf4a6eb
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "GnssNavMsgCallback"
+
+#include "GnssNavigationMessageCallback.h"
+#include <log/log.h>
+
+android::binder::Status GnssNavigationMessageCallback::gnssNavigationMessageCb(
+        const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage& msg) {
+    ALOGD("gnssNavigationMessageCb. svid=%d, type=%d, status=%d, msgId=%d, subMsgId=%d, "
+          "data.size=%d",
+          msg.svid, (int)msg.type, (int)msg.status, msg.messageId, msg.submessageId,
+          (int)msg.data.size());
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.h b/gnss/aidl/vts/GnssNavigationMessageCallback.h
new file mode 100644
index 0000000..55114ca
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssNavigationMessageCallback.h>
+
+/** Implementation for IGnssNavigationMessageCallback. */
+class GnssNavigationMessageCallback
+    : public android::hardware::gnss::BnGnssNavigationMessageCallback {
+  public:
+    GnssNavigationMessageCallback() {}
+    ~GnssNavigationMessageCallback() {}
+
+    android::binder::Status gnssNavigationMessageCb(
+            const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage&
+                    message) override;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index f72f7fe..e3ecbed 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -23,6 +23,7 @@
 #include <binder/IServiceManager.h>
 
 #include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssBatchingCallback.h"
 #include "GnssCallbackAidl.h"
 #include "v2_1/gnss_hal_test_template.h"
 
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 0cd782e..aac59db 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -16,12 +16,18 @@
 
 #define LOG_TAG "GnssHalTestCases"
 
+#include <android/hardware/gnss/IAGnss.h>
 #include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssBatching.h>
 #include <android/hardware/gnss/IGnssMeasurementCallback.h>
 #include <android/hardware/gnss/IGnssMeasurementInterface.h>
 #include <android/hardware/gnss/IGnssPowerIndication.h>
 #include <android/hardware/gnss/IGnssPsds.h>
+#include "AGnssCallbackAidl.h"
+#include "GnssBatchingCallback.h"
+#include "GnssGeofenceCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
+#include "GnssNavigationMessageCallback.h"
 #include "GnssPowerIndicationCallback.h"
 #include "gnss_hal_test.h"
 
@@ -32,10 +38,16 @@
 using android::hardware::gnss::GnssData;
 using android::hardware::gnss::GnssMeasurement;
 using android::hardware::gnss::GnssPowerStats;
+using android::hardware::gnss::IAGnss;
 using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssBatching;
+using android::hardware::gnss::IGnssBatchingCallback;
 using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssGeofence;
+using android::hardware::gnss::IGnssGeofenceCallback;
 using android::hardware::gnss::IGnssMeasurementCallback;
 using android::hardware::gnss::IGnssMeasurementInterface;
+using android::hardware::gnss::IGnssNavigationMessageInterface;
 using android::hardware::gnss::IGnssPowerIndication;
 using android::hardware::gnss::IGnssPsds;
 using android::hardware::gnss::PsdsType;
@@ -749,3 +761,62 @@
     status = gnss_configuration_hal->setBlocklist(sources);
     ASSERT_TRUE(status.isOk());
 }
+
+/*
+ * TestAllExtensions.
+ */
+TEST_P(GnssHalTest, TestAllExtensions) {
+    sp<IGnssBatching> iGnssBatching;
+    auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
+    if (status.isOk() && iGnssBatching != nullptr) {
+        auto gnssBatchingCallback = sp<GnssBatchingCallback>::make();
+        status = iGnssBatching->init(gnssBatchingCallback);
+        ASSERT_TRUE(status.isOk());
+
+        status = iGnssBatching->cleanup();
+        ASSERT_TRUE(status.isOk());
+    }
+
+    sp<IGnssGeofence> iGnssGeofence;
+    status = aidl_gnss_hal_->getExtensionGnssGeofence(&iGnssGeofence);
+    if (status.isOk() && iGnssGeofence != nullptr) {
+        auto gnssGeofenceCallback = sp<GnssGeofenceCallback>::make();
+        status = iGnssGeofence->setCallback(gnssGeofenceCallback);
+        ASSERT_TRUE(status.isOk());
+    }
+
+    sp<IGnssNavigationMessageInterface> iGnssNavMsgIface;
+    status = aidl_gnss_hal_->getExtensionGnssNavigationMessage(&iGnssNavMsgIface);
+    if (status.isOk() && iGnssNavMsgIface != nullptr) {
+        auto gnssNavMsgCallback = sp<GnssNavigationMessageCallback>::make();
+        status = iGnssNavMsgIface->setCallback(gnssNavMsgCallback);
+        ASSERT_TRUE(status.isOk());
+
+        status = iGnssNavMsgIface->close();
+        ASSERT_TRUE(status.isOk());
+    }
+}
+
+/*
+ * TestAGnssExtension:
+ * 1. Gets the IAGnss extension.
+ * 2. Sets AGnssCallback.
+ * 3. Sets SUPL server host/port.
+ */
+TEST_P(GnssHalTest, TestAGnssExtension) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    sp<IAGnss> iAGnss;
+    auto status = aidl_gnss_hal_->getExtensionAGnss(&iAGnss);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iAGnss != nullptr);
+
+    auto agnssCallback = sp<AGnssCallbackAidl>::make();
+    status = iAGnss->setCallback(agnssCallback);
+    ASSERT_TRUE(status.isOk());
+
+    // Set SUPL server host/port
+    status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+    ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 5294409..05bec88 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -56,6 +56,6 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
-        "android.hardware.gnss-V1-ndk",
+        "android.hardware.gnss-V2-ndk",
     ],
 }
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index dfcf9a9..c339e72 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -28,6 +28,7 @@
 using aidl::android::hardware::gnss::ElapsedRealtime;
 using aidl::android::hardware::gnss::GnssClock;
 using aidl::android::hardware::gnss::GnssData;
+using aidl::android::hardware::gnss::GnssLocation;
 using aidl::android::hardware::gnss::GnssMeasurement;
 using aidl::android::hardware::gnss::IGnss;
 using aidl::android::hardware::gnss::IGnssMeasurementCallback;
@@ -232,6 +233,30 @@
     return gnssData;
 }
 
+GnssLocation Utils::getMockLocation() {
+    ElapsedRealtime elapsedRealtime = {
+            .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = ::android::elapsedRealtimeNano(),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+    GnssLocation location = {.gnssLocationFlags = 0xFF,
+                             .latitudeDegrees = gMockLatitudeDegrees,
+                             .longitudeDegrees = gMockLongitudeDegrees,
+                             .altitudeMeters = gMockAltitudeMeters,
+                             .speedMetersPerSec = gMockSpeedMetersPerSec,
+                             .bearingDegrees = gMockBearingDegrees,
+                             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+                             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+                             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+                             .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+                             .timestampMillis = static_cast<int64_t>(
+                                     kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6),
+                             .elapsedRealtime = elapsedRealtime};
+    return location;
+}
+
 V2_0::GnssLocation Utils::getMockLocationV2_0() {
     const V2_0::ElapsedRealtime timestamp = {
             .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 43772ce..4500ee6 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -17,6 +17,7 @@
 #ifndef android_hardware_gnss_common_default_Utils_H_
 #define android_hardware_gnss_common_default_Utils_H_
 
+#include <aidl/android/hardware/gnss/BnGnss.h>
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <android/hardware/gnss/1.0/IGnss.h>
 #include <android/hardware/gnss/2.0/IGnss.h>
@@ -34,6 +35,7 @@
             const bool enableCorrVecOutputs);
     static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
     static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+    static aidl::android::hardware::gnss::GnssLocation getMockLocation();
     static V2_0::GnssLocation getMockLocationV2_0();
     static V1_0::GnssLocation getMockLocationV1_0();
     static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 19b1b45..c5a186b 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -523,7 +523,7 @@
     using Capabilities = V2_1::IGnssCallback::Capabilities;
     const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
                               Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
-                              Capabilities::ANTENNA_INFO;
+                              Capabilities::ANTENNA_INFO | Capabilities::NAV_MESSAGES;
     auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
     if (!ret.isOk()) {
         ALOGE("%s: Unable to invoke callback", __func__);
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 9c84e80..be22ff6 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -24,12 +24,10 @@
 namespace gnss {
 namespace common {
 
-using GnssConstellationType_V1_0 = V1_0::GnssConstellationType;
-using GnssConstellationType_V2_0 = V2_0::GnssConstellationType;
-
+using namespace measurement_corrections::V1_0;
 using V1_0::GnssLocationFlags;
 
-void Utils::checkLocation(const GnssLocation& location, bool check_speed,
+void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
                           bool check_more_accuracies) {
     EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
     EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
@@ -96,7 +94,7 @@
     EXPECT_GT(location.timestamp, 1.48e12);
 }
 
-const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
+const MeasurementCorrections Utils::getMockMeasurementCorrections() {
     ReflectingPlane reflectingPlane = {
             .latitudeDegrees = 37.4220039,
             .longitudeDegrees = -122.0840991,
@@ -104,12 +102,12 @@
             .azimuthDegrees = 203.0,
     };
 
-    SingleSatCorrection_V1_0 singleSatCorrection1 = {
+    SingleSatCorrection singleSatCorrection1 = {
             .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC |
                                         GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE,
-            .constellation = GnssConstellationType_V1_0::GPS,
+            .constellation = V1_0::GnssConstellationType::GPS,
             .svid = 12,
             .carrierFrequencyHz = 1.59975e+09,
             .probSatIsLos = 0.50001,
@@ -117,11 +115,11 @@
             .excessPathLengthUncertaintyMeters = 25.5,
             .reflectingPlane = reflectingPlane,
     };
-    SingleSatCorrection_V1_0 singleSatCorrection2 = {
+    SingleSatCorrection singleSatCorrection2 = {
             .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
                                         GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC,
-            .constellation = GnssConstellationType_V1_0::GPS,
+            .constellation = V1_0::GnssConstellationType::GPS,
             .svid = 9,
             .carrierFrequencyHz = 1.59975e+09,
             .probSatIsLos = 0.873,
@@ -129,9 +127,9 @@
             .excessPathLengthUncertaintyMeters = 10.0,
     };
 
-    hidl_vec<SingleSatCorrection_V1_0> singleSatCorrections = {singleSatCorrection1,
-                                                               singleSatCorrection2};
-    MeasurementCorrections_1_0 mockCorrections = {
+    hidl_vec<SingleSatCorrection> singleSatCorrections = {singleSatCorrection1,
+                                                          singleSatCorrection2};
+    MeasurementCorrections mockCorrections = {
             .latitudeDegrees = 37.4219999,
             .longitudeDegrees = -122.0840575,
             .altitudeMeters = 30.60062531,
@@ -143,25 +141,26 @@
     return mockCorrections;
 }
 
-const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
-    MeasurementCorrections_1_0 mockCorrections_1_0 = getMockMeasurementCorrections();
+const measurement_corrections::V1_1::MeasurementCorrections
+Utils::getMockMeasurementCorrections_1_1() {
+    MeasurementCorrections mockCorrections_1_0 = getMockMeasurementCorrections();
 
-    SingleSatCorrection_V1_1 singleSatCorrection1 = {
+    measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection1 = {
             .v1_0 = mockCorrections_1_0.satCorrections[0],
-            .constellation = GnssConstellationType_V2_0::IRNSS,
+            .constellation = V2_0::GnssConstellationType::IRNSS,
     };
-    SingleSatCorrection_V1_1 singleSatCorrection2 = {
+    measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection2 = {
             .v1_0 = mockCorrections_1_0.satCorrections[1],
-            .constellation = GnssConstellationType_V2_0::IRNSS,
+            .constellation = V2_0::GnssConstellationType::IRNSS,
     };
 
-    mockCorrections_1_0.satCorrections[0].constellation = GnssConstellationType_V1_0::UNKNOWN;
-    mockCorrections_1_0.satCorrections[1].constellation = GnssConstellationType_V1_0::UNKNOWN;
+    mockCorrections_1_0.satCorrections[0].constellation = V1_0::GnssConstellationType::UNKNOWN;
+    mockCorrections_1_0.satCorrections[1].constellation = V1_0::GnssConstellationType::UNKNOWN;
 
-    hidl_vec<SingleSatCorrection_V1_1> singleSatCorrections = {singleSatCorrection1,
-                                                               singleSatCorrection2};
+    hidl_vec<measurement_corrections::V1_1::SingleSatCorrection> singleSatCorrections = {
+            singleSatCorrection1, singleSatCorrection2};
 
-    MeasurementCorrections_1_1 mockCorrections_1_1 = {
+    measurement_corrections::V1_1::MeasurementCorrections mockCorrections_1_1 = {
             .v1_0 = mockCorrections_1_0,
             .hasEnvironmentBearing = true,
             .environmentBearingDegrees = 45.0,
@@ -177,22 +176,22 @@
  * GnssConstellationType_1_0 type constellation. For constellations that do not have
  * an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
  */
-GnssConstellationType_1_0 Utils::mapConstellationType(GnssConstellationType_2_0 constellation) {
+V1_0::GnssConstellationType Utils::mapConstellationType(V2_0::GnssConstellationType constellation) {
     switch (constellation) {
-        case GnssConstellationType_2_0::GPS:
-            return GnssConstellationType_1_0::GPS;
-        case GnssConstellationType_2_0::SBAS:
-            return GnssConstellationType_1_0::SBAS;
-        case GnssConstellationType_2_0::GLONASS:
-            return GnssConstellationType_1_0::GLONASS;
-        case GnssConstellationType_2_0::QZSS:
-            return GnssConstellationType_1_0::QZSS;
-        case GnssConstellationType_2_0::BEIDOU:
-            return GnssConstellationType_1_0::BEIDOU;
-        case GnssConstellationType_2_0::GALILEO:
-            return GnssConstellationType_1_0::GALILEO;
+        case V2_0::GnssConstellationType::GPS:
+            return V1_0::GnssConstellationType::GPS;
+        case V2_0::GnssConstellationType::SBAS:
+            return V1_0::GnssConstellationType::SBAS;
+        case V2_0::GnssConstellationType::GLONASS:
+            return V1_0::GnssConstellationType::GLONASS;
+        case V2_0::GnssConstellationType::QZSS:
+            return V1_0::GnssConstellationType::QZSS;
+        case V2_0::GnssConstellationType::BEIDOU:
+            return V1_0::GnssConstellationType::BEIDOU;
+        case V2_0::GnssConstellationType::GALILEO:
+            return V1_0::GnssConstellationType::GALILEO;
         default:
-            return GnssConstellationType_1_0::UNKNOWN;
+            return V1_0::GnssConstellationType::UNKNOWN;
     }
 }
 
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index a4aad80..91c1167 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -22,33 +22,21 @@
 #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
 #include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
 
-using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
-using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
-using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
-using namespace android::hardware::gnss::measurement_corrections::V1_0;
-
-using MeasurementCorrections_1_0 =
-        android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
-using MeasurementCorrections_1_1 =
-        android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
-
-using SingleSatCorrection_V1_0 =
-        android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
-using SingleSatCorrection_V1_1 =
-        android::hardware::gnss::measurement_corrections::V1_1::SingleSatCorrection;
-
 namespace android {
 namespace hardware {
 namespace gnss {
 namespace common {
 
 struct Utils {
-    static void checkLocation(const GnssLocation& location, bool check_speed,
+    static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
                               bool check_more_accuracies);
-    static const MeasurementCorrections_1_0 getMockMeasurementCorrections();
-    static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
+    static const measurement_corrections::V1_0::MeasurementCorrections
+    getMockMeasurementCorrections();
+    static const measurement_corrections::V1_1::MeasurementCorrections
+    getMockMeasurementCorrections_1_1();
 
-    static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
+    static V1_0::GnssConstellationType mapConstellationType(
+            V2_0::GnssConstellationType constellation);
 
     static bool isAutomotiveDevice();
 };
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
index 04a863b..512fecb 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
@@ -63,4 +63,5 @@
   STENCIL_8 = 53,
   YCBCR_P010 = 54,
   HSV_888 = 55,
+  R_8 = 56,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
similarity index 92%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
index cfafc50..3722803 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.common;
+@VintfStability
+parcelable Point {
+  int x;
+  int y;
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
index eb87f8d..4e891f6 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -498,4 +498,11 @@
      * interpretation is defined by the dataspace.
      */
     HSV_888 = 0x37,
+
+    /**
+     * 8 bit format with a single 8-bit component.
+     *
+     * The component values are unsigned normalized to the range [0, 1].
+     */
+    R_8 = 0x38,
 }
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
similarity index 68%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to graphics/common/aidl/android/hardware/graphics/common/Point.aidl
index 7f385de..b3ede44 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
+/**
+ * Copyright (c) 2021, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.graphics.common;
+
+/**
+ * General purpose definition of a point.
+ */
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+parcelable Point {
+    int x;
+    int y;
 }
diff --git a/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h b/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
index 33012e9..18a50fe 100644
--- a/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
+++ b/graphics/composer/2.2/utils/resources/include/composer-resources/2.2/ComposerResources.h
@@ -29,6 +29,8 @@
 namespace V2_2 {
 namespace hal {
 
+using V2_1::Display;
+using V2_1::Error;
 using V2_1::hal::ComposerHandleCache;
 using V2_1::hal::ComposerHandleImporter;
 
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 5c085cb..4faf84b 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -43,6 +43,8 @@
         "libmath",
         "libnativewindow",
         "librenderengine",
+        "libshaders",
+        "libtonemap",
         "android.hardware.graphics.mapper@3.0",
         "android.hardware.graphics.mapper@3.0-vts",
         "android.hardware.graphics.mapper@4.0",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 36f3c00..1e0a329 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -67,6 +67,8 @@
         "android.hardware.graphics.mapper@4.0-vts",
         "libgtest",
         "librenderengine",
+        "libshaders",
+        "libtonemap",
     ],
     header_libs: [
         "android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index e33c653..9034138 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,12 +31,14 @@
         enabled: true,
         support_system_process: true,
     },
-    srcs: ["android/hardware/graphics/composer3/*.aidl"],
+    srcs: [
+        "android/hardware/graphics/composer3/*.aidl",
+        "android/hardware/graphics/composer3/command/*.aidl",
+    ],
     stability: "vintf",
     imports: [
         "android.hardware.graphics.common-V3",
         "android.hardware.common-V2",
-        "android.hardware.common.fmq-V1",
     ],
     backend: {
         cpp: {
@@ -73,6 +75,7 @@
     vendor_available: true,
     shared_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
+        "android.hardware.common-V2-ndk",
         "libbase",
         "libfmq",
         "libsync",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
deleted file mode 100644
index a522d53..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ /dev/null
@@ -1,41 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index e19105d..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,76 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum Command {
-  LENGTH_MASK = 65535,
-  OPCODE_SHIFT = 16,
-  OPCODE_MASK = -65536,
-  SELECT_DISPLAY = 0,
-  SELECT_LAYER = 65536,
-  SET_ERROR = 16777216,
-  SET_CHANGED_COMPOSITION_TYPES = 16842752,
-  SET_DISPLAY_REQUESTS = 16908288,
-  SET_PRESENT_FENCE = 16973824,
-  SET_RELEASE_FENCES = 17039360,
-  SET_COLOR_TRANSFORM = 33554432,
-  SET_CLIENT_TARGET = 33619968,
-  SET_OUTPUT_BUFFER = 33685504,
-  VALIDATE_DISPLAY = 33751040,
-  ACCEPT_DISPLAY_CHANGES = 33816576,
-  PRESENT_DISPLAY = 33882112,
-  PRESENT_OR_VALIDATE_DISPLAY = 33947648,
-  SET_LAYER_CURSOR_POSITION = 50331648,
-  SET_LAYER_BUFFER = 50397184,
-  SET_LAYER_SURFACE_DAMAGE = 50462720,
-  SET_LAYER_BLEND_MODE = 67108864,
-  SET_LAYER_COLOR = 67174400,
-  SET_LAYER_COMPOSITION_TYPE = 67239936,
-  SET_LAYER_DATASPACE = 67305472,
-  SET_LAYER_DISPLAY_FRAME = 67371008,
-  SET_LAYER_PLANE_ALPHA = 67436544,
-  SET_LAYER_SIDEBAND_STREAM = 67502080,
-  SET_LAYER_SOURCE_CROP = 67567616,
-  SET_LAYER_TRANSFORM = 67633152,
-  SET_LAYER_VISIBLE_REGION = 67698688,
-  SET_LAYER_Z_ORDER = 67764224,
-  SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 67829760,
-  SET_LAYER_PER_FRAME_METADATA = 50528256,
-  SET_LAYER_FLOAT_COLOR = 67895296,
-  SET_LAYER_COLOR_TRANSFORM = 67960832,
-  SET_LAYER_PER_FRAME_METADATA_BLOBS = 50593792,
-  SET_CLIENT_TARGET_PROPERTY = 17104896,
-  SET_LAYER_GENERIC_METADATA = 68026368,
-  SET_LAYER_WHITE_POINT_NITS = 50659328,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
deleted file mode 100644
index 26e7d97..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ /dev/null
@@ -1,39 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index d7cab2b..65cf86c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -38,7 +38,7 @@
   android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
   void destroyLayer(long display, long layer);
   void destroyVirtualDisplay(long display);
-  android.hardware.graphics.composer3.ExecuteCommandsStatus executeCommands(int inLength, in android.hardware.common.NativeHandle[] inHandles);
+  android.hardware.graphics.composer3.command.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.command.CommandPayload[] commands);
   int getActiveConfig(long display);
   android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
   float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
@@ -56,7 +56,6 @@
   android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
   android.hardware.graphics.composer3.LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
   int getMaxVirtualDisplayCount();
-  android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> getOutputCommandQueue();
   android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
   android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
   ParcelFileDescriptor getReadbackBufferFence(long display);
@@ -71,7 +70,6 @@
   void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
   void setDisplayBrightness(long display, float brightness);
   void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
-  void setInputCommandQueue(in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> descriptor);
   void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
   void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in ParcelFileDescriptor releaseFence);
   void setVsyncEnabled(long display, boolean enabled);
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
index 41a1afe..cead848 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -31,10 +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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable Buffer {
+  int slot;
+  @nullable android.hardware.common.NativeHandle handle;
+  @nullable ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
index 41a1afe..1377c6c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -31,10 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ChangedCompositionTypes {
+  long display;
+  android.hardware.graphics.composer3.command.ChangedCompositionTypes.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    android.hardware.graphics.composer3.Composition composition;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
index 41a1afe..c3f4700 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -31,10 +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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ClientTarget {
+  android.hardware.graphics.composer3.command.Buffer buffer;
+  android.hardware.graphics.common.Dataspace dataspace;
+  android.hardware.graphics.common.Rect[] damage;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
index 41a1afe..b690a57 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -31,10 +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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ClientTargetPropertyWithNits {
+  long display;
+  android.hardware.graphics.composer3.ClientTargetProperty clientTargetProperty;
+  float whitePointNits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index 41a1afe..0b3071c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -31,10 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ColorTransformPayload {
+  float[] matrix;
+  android.hardware.graphics.common.ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
index 41a1afe..9848306 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -31,10 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+union CommandPayload {
+  android.hardware.graphics.composer3.command.DisplayCommand displayCommand;
+  android.hardware.graphics.composer3.command.LayerCommand layerCommand;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
index 41a1afe..1b3cae8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -31,10 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+union CommandResultPayload {
+  android.hardware.graphics.composer3.command.Error error;
+  android.hardware.graphics.composer3.command.ChangedCompositionTypes changedCompositionType;
+  android.hardware.graphics.composer3.command.DisplayRequest displayRequest;
+  android.hardware.graphics.composer3.command.PresentFence presentFence;
+  android.hardware.graphics.composer3.command.ReleaseFences releaseFences;
+  android.hardware.graphics.composer3.command.PresentOrValidate presentOrValidateResult;
+  android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits clientTargetProperty;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
similarity index 77%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
index 41a1afe..7446db0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -31,10 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable DisplayCommand {
+  long display;
+  @nullable android.hardware.graphics.composer3.command.ColorTransformPayload colorTransform;
+  @nullable android.hardware.graphics.composer3.command.ClientTarget clientTarget;
+  @nullable android.hardware.graphics.composer3.command.Buffer virtualDisplayOutputBuffer;
+  boolean validateDisplay;
+  boolean acceptDisplayChanges;
+  boolean presentDisplay;
+  boolean presentOrValidateDisplay;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
index 41a1afe..7f413a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -31,10 +31,18 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable DisplayRequest {
+  long display;
+  int mask;
+  android.hardware.graphics.composer3.command.DisplayRequest.LayerRequest[] layerRequests;
+  const int FLIP_CLIENT_TARGET = 1;
+  const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+  @VintfStability
+  parcelable LayerRequest {
+    long layer;
+    int mask;
+    const int CLEAR_CLIENT_TARGET = 1;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
index cfafc50..1726ea5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable Error {
+  int commandIndex;
+  int errorCode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index 41a1afe..be889d8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -31,10 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable GenericMetadata {
+  android.hardware.graphics.composer3.LayerGenericMetadataKey key;
+  byte[] value;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..b5adbc3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable LayerCommand {
+  long display;
+  long layer;
+  @nullable android.hardware.graphics.common.Point cursorPosition;
+  @nullable android.hardware.graphics.composer3.command.Buffer buffer;
+  @nullable android.hardware.graphics.common.Rect[] damage;
+  @nullable android.hardware.graphics.composer3.command.ParcelableBlendMode blendMode;
+  @nullable android.hardware.graphics.composer3.Color color;
+  @nullable android.hardware.graphics.composer3.FloatColor floatColor;
+  @nullable android.hardware.graphics.composer3.command.ParcelableComposition composition;
+  @nullable android.hardware.graphics.composer3.command.ParcelableDataspace dataspace;
+  @nullable android.hardware.graphics.common.Rect displayFrame;
+  @nullable android.hardware.graphics.composer3.command.PlaneAlpha planeAlpha;
+  @nullable android.hardware.common.NativeHandle sidebandStream;
+  @nullable android.hardware.graphics.common.FRect sourceCrop;
+  @nullable android.hardware.graphics.composer3.command.ParcelableTransform transform;
+  @nullable android.hardware.graphics.common.Rect[] visibleRegion;
+  @nullable android.hardware.graphics.composer3.command.ZOrder z;
+  @nullable float[] colorTransform;
+  @nullable android.hardware.graphics.composer3.command.WhitePointNits whitePointNits;
+  @nullable android.hardware.graphics.composer3.command.GenericMetadata genericMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 41a1afe..5e6d212 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -31,10 +31,8 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ParcelableBlendMode {
+  android.hardware.graphics.common.BlendMode blendMode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 41a1afe..40637a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -31,10 +31,8 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ParcelableComposition {
+  android.hardware.graphics.composer3.Composition composition;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 90%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 41a1afe..8f06079 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -31,10 +31,8 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ParcelableDataspace {
+  android.hardware.graphics.common.Dataspace dataspace;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 41a1afe..6d6fe5b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -31,10 +31,8 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ParcelableTransform {
+  android.hardware.graphics.common.Transform transform;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index cfafc50..97f5329 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PlaneAlpha {
+  float alpha;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 91%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
index cfafc50..906f20c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PresentFence {
+  long display;
+  ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index 41a1afe..66f1c03 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -31,10 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable PresentOrValidate {
+  long display;
+  android.hardware.graphics.composer3.command.PresentOrValidate.Result result;
+  @VintfStability
+  enum Result {
+    Presented = 0,
+    Validated = 1,
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
index 41a1afe..b7d2586 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -31,10 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ReleaseFences {
+  long display;
+  android.hardware.graphics.composer3.command.ReleaseFences.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    ParcelFileDescriptor fence;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
index cfafc50..2b25167 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable WhitePointNits {
+  float nits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
index cfafc50..69b68c4 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ZOrder {
+  int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index 95c07ac..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,763 +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.graphics.composer3;
-
-import android.hardware.graphics.composer3.Command;
-
-/**
- * The command interface allows composer3 to reduce binder overhead by sending
- * atomic command stream in a command message queue. These commands are usually
- * sent on a per frame basic and contains the information that describes how the
- * display is composited. @see IComposerClient.executeCommands.
- */
-@VintfStability
-@Backing(type="int")
-enum Command {
-    LENGTH_MASK = 0xffff,
-    OPCODE_SHIFT = 16,
-    OPCODE_MASK = 0xffff << OPCODE_SHIFT,
-
-    // special commands
-
-    /**
-     * SELECT_DISPLAY has this pseudo prototype
-     *
-     *   selectDisplay(long display);
-     *
-     * Selects the current display implied by all other commands.
-     *
-     * @param display is the newly selected display.
-     */
-    SELECT_DISPLAY = 0x000 << OPCODE_SHIFT,
-
-    /**
-     * SELECT_LAYER has this pseudo prototype
-     *
-     *   selectLayer(long layer);
-     *
-     * Selects the current layer implied by all implicit layer commands.
-     *
-     * @param layer is the newly selected layer.
-     */
-    SELECT_LAYER = 0x001 << OPCODE_SHIFT,
-
-    // value commands (for return values)
-
-    /**
-     * SET_ERROR has this pseudo prototype
-     *
-     *   setError(uint32_t location, int error);
-     *
-     * Indicates an error generated by a command.
-     *
-     * @param location is the offset of the command in the input command
-     *        message queue.
-     * @param error is the error generated by the command.
-     */
-    SET_ERROR = 0x100 << OPCODE_SHIFT,
-
-    /**
-     * SET_CHANGED_COMPOSITION_TYPES has this pseudo prototype
-     *
-     *   setChangedCompositionTypes(long[] layers,
-     *                              Composition[] types);
-     *
-     * Sets the layers for which the device requires a different composition
-     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
-     * client must either update its state with these types and call
-     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
-     * the display again.
-     *
-     * @param layers is an array of layer handles.
-     * @param types is an array of composition types, each corresponding to
-     *         an element of layers.
-     */
-    SET_CHANGED_COMPOSITION_TYPES = 0x101 << OPCODE_SHIFT,
-
-    /**
-     * SET_DISPLAY_REQUESTS has this pseudo prototype
-     *
-     *   setDisplayRequests(int displayRequestMask,
-     *                      long[] layers,
-     *                      int[] layerRequestMasks);
-     *
-     * Sets the display requests and the layer requests required for the last
-     * validated configuration.
-     *
-     * Display requests provide information about how the client must handle
-     * the client target. Layer requests provide information about how the
-     * client must handle an individual layer.
-     *
-     * @param displayRequestMask is the display requests for the current
-     *        validated state.
-     * @param layers is an array of layers which all have at least one
-     *        request.
-     * @param layerRequestMasks is the requests corresponding to each element
-     *        of layers.
-     */
-    SET_DISPLAY_REQUESTS = 0x102 << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_FENCE has this pseudo prototype
-     *
-     *   setPresentFence(int presentFenceIndex);
-     *
-     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
-     * displays, this fence must be signaled at the vsync when the result
-     * of composition of this frame starts to appear (for video-mode panels)
-     * or starts to transfer to panel memory (for command-mode panels). For
-     * virtual displays, this fence must be signaled when writes to the output
-     * buffer have completed and it is safe to read from it.
-     *
-     * @param presentFenceIndex is an index into outHandles array.
-     */
-    SET_PRESENT_FENCE = 0x103 << OPCODE_SHIFT,
-
-    /**
-     * SET_RELEASE_FENCES has this pseudo prototype
-     *
-     *   setReleaseFences(long[] layers,
-     *                    int[] releaseFenceIndices);
-     *
-     * Sets the release fences for device layers on this display which will
-     * receive new buffer contents this frame.
-     *
-     * A release fence is a file descriptor referring to a sync fence object
-     * which must be signaled after the device has finished reading from the
-     * buffer presented in the prior frame. This indicates that it is safe to
-     * start writing to the buffer again. If a given layer's fence is not
-     * returned from this function, it must be assumed that the buffer
-     * presented on the previous frame is ready to be written.
-     *
-     * The fences returned by this function must be unique for each layer
-     * (even if they point to the same underlying sync object).
-     *
-     * @param layers is an array of layer handles.
-     * @param releaseFenceIndices are indices into outHandles array, each
-     *        corresponding to an element of layers.
-     */
-    SET_RELEASE_FENCES = 0x104 << OPCODE_SHIFT,
-
-    // display commands
-
-    /**
-     * SET_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setColorTransform(float[16] matrix,
-     *                     ColorTransform hint);
-     *
-     * Sets a color transform which will be applied after composition.
-     *
-     * If hint is not ColorTransform::ARBITRARY, then the device may use the
-     * hint to apply the desired color transform instead of using the color
-     * matrix directly.
-     *
-     * If the device is not capable of either using the hint or the matrix to
-     * apply the desired color transform, it must force all layers to client
-     * composition during VALIDATE_DISPLAY.
-     *
-     * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
-     * the client must never apply the color transform during client
-     * composition, even if all layers are being composed by the client.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
-     * output color [R_out, G_out, B_out] will be:
-     *
-     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
-     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
-     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     * @param hint is a hint value which may be used instead of the given
-     *        matrix unless it is ColorTransform::ARBITRARY.
-     */
-    SET_COLOR_TRANSFORM = 0x200 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET has this pseudo prototype
-     *
-     *   setClientTarget(int targetSlot,
-     *                   int targetIndex,
-     *                   int acquireFenceIndex,
-     *                   android.hardware.graphics.common.Dataspace dataspace,
-     *                   Rect[] damage);
-     *
-     * Sets the buffer handle which will receive the output of client
-     * composition.  Layers marked as Composition::CLIENT must be composited
-     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
-     * marked as Composition::CLIENT must be composited with this buffer by
-     * the device.
-     *
-     * The buffer handle provided may be empty if no layers are being
-     * composited by the client. This must not result in an error (unless an
-     * invalid display handle is also provided).
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the client
-     * target buffer.  If it is already safe to read from this buffer, an
-     * empty handle may be passed instead.
-     *
-     * For more about dataspaces, see SET_LAYER_DATASPACE.
-     *
-     * The damage parameter describes a surface damage region as defined in
-     * the description of SET_LAYER_SURFACE_DAMAGE.
-     *
-     * Will be called before PRESENT_DISPLAY if any of the layers are marked
-     * as Composition::CLIENT. If no layers are so marked, then it is not
-     * necessary to call this function. It is not necessary to call
-     * validateDisplay after changing the target through this function.
-     *
-     * @param targetSlot is the client target buffer slot to use.
-     * @param targetIndex is an index into inHandles for the new target
-     *        buffer.
-     * @param acquireFenceIndex is an index into inHandles for a sync fence
-     *        file descriptor as described above.
-     * @param dataspace is the dataspace of the buffer, as described in
-     *        setLayerDataspace.
-     * @param damage is the surface damage region.
-     *
-     */
-    SET_CLIENT_TARGET = 0x201 << OPCODE_SHIFT,
-
-    /**
-     * SET_OUTPUT_BUFFER has this pseudo prototype
-     *
-     *   setOutputBuffer(int bufferSlot,
-     *                   int bufferIndex,
-     *                   int releaseFenceIndex);
-     *
-     * Sets the output buffer for a virtual display. That is, the buffer to
-     * which the composition result will be written.
-     *
-     * Also provides a file descriptor referring to a release sync fence
-     * object, which must be signaled when it is safe to write to the output
-     * buffer. If it is already safe to write to the output buffer, an empty
-     * handle may be passed instead.
-     *
-     * Must be called at least once before PRESENT_DISPLAY, but does not have
-     * any interaction with layer state or display validation.
-     *
-     * @param bufferSlot is the new output buffer.
-     * @param bufferIndex is the new output buffer.
-     * @param releaseFenceIndex is a sync fence file descriptor as described
-     *        above.
-     */
-    SET_OUTPUT_BUFFER = 0x202 << OPCODE_SHIFT,
-
-    /**
-     * VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   validateDisplay();
-     *
-     * Instructs the device to inspect all of the layer state and determine if
-     * there are any composition type changes necessary before presenting the
-     * display. Permitted changes are described in the definition of
-     * Composition above.
-     */
-    VALIDATE_DISPLAY = 0x203 << OPCODE_SHIFT,
-
-    /**
-     * ACCEPT_DISPLAY_CHANGES has this pseudo prototype
-     *
-     *   acceptDisplayChanges();
-     *
-     * Accepts the changes required by the device from the previous
-     * validateDisplay call (which may be queried using
-     * getChangedCompositionTypes) and revalidates the display. This function
-     * is equivalent to requesting the changed types from
-     * getChangedCompositionTypes, setting those types on the corresponding
-     * layers, and then calling validateDisplay again.
-     *
-     * After this call it must be valid to present this display. Calling this
-     * after validateDisplay returns 0 changes must succeed with NONE, but
-     * must have no other effect.
-     */
-    ACCEPT_DISPLAY_CHANGES = 0x204 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_DISPLAY has this pseudo prototype
-     *
-     *   presentDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer).
-     *
-     * Prior to calling this function, the display must be successfully
-     * validated with validateDisplay. Note that setLayerBuffer and
-     * setLayerSurfaceDamage specifically do not count as layer state, so if
-     * there are no other changes to the layer state (or to the buffer's
-     * properties as described in setLayerBuffer), then it is safe to call
-     * this function without first validating the display.
-     */
-    PRESENT_DISPLAY = 0x205 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_OR_VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   presentOrValidateDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer) if validate can be skipped,
-     * or perform a VALIDATE_DISPLAY action instead.
-     */
-    PRESENT_OR_VALIDATE_DISPLAY = 0x206 << OPCODE_SHIFT,
-
-    // layer commands (VALIDATE_DISPLAY not required)
-
-    /**
-     * SET_LAYER_CURSOR_POSITION has this pseudo prototype
-     *
-     *   setLayerCursorPosition(int x, int y);
-     *
-     * Asynchronously sets the position of a cursor layer.
-     *
-     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
-     * If validation succeeds (i.e., the device does not request a composition
-     * change for that layer), then once a buffer has been set for the layer
-     * and it has been presented, its position may be set by this function at
-     * any time between presentDisplay and any subsequent validateDisplay
-     * calls for this display.
-     *
-     * Once validateDisplay is called, this function must not be called again
-     * until the validate/present sequence is completed.
-     *
-     * May be called from any thread so long as it is not interleaved with the
-     * validate/present sequence as described above.
-     *
-     * @param layer is the layer to which the position is set.
-     * @param x is the new x coordinate (in pixels from the left of the
-     *        screen).
-     * @param y is the new y coordinate (in pixels from the top of the
-     *        screen).
-     */
-    SET_LAYER_CURSOR_POSITION = 0x300 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_BUFFER has this pseudo prototype
-     *
-     *   setLayerBuffer(int bufferSlot,
-     *                  int bufferIndex,
-     *                  int acquireFenceIndex);
-     *
-     * Sets the buffer handle to be displayed for this layer. If the buffer
-     * properties set at allocation time (width, height, format, and usage)
-     * have not changed since the previous frame, it is not necessary to call
-     * validateDisplay before calling presentDisplay unless new state needs to
-     * be validated in the interim.
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the given
-     * buffer. If it is already safe to read from the buffer, an empty handle
-     * may be passed instead.
-     *
-     * This function must return NONE and have no other effect if called for a
-     * layer with a composition type of Composition::SOLID_COLOR (because it
-     * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
-     * synchronization and buffer updates for these layers are handled
-     * elsewhere).
-     *
-     * @param layer is the layer to which the buffer is set.
-     * @param bufferSlot is the buffer slot to use.
-     * @param bufferIndex is the buffer handle to set.
-     * @param acquireFenceIndex is a sync fence file descriptor as described above.
-     */
-    SET_LAYER_BUFFER = 0x301 << OPCODE_SHIFT,
-
-    /*
-     * SET_LAYER_SURFACE_DAMAGE has this pseudo prototype
-     *
-     *   setLayerSurfaceDamage(Rect[] damage);
-     *
-     * Provides the region of the source buffer which has been modified since
-     * the last frame. This region does not need to be validated before
-     * calling presentDisplay.
-     *
-     * Once set through this function, the damage region remains the same
-     * until a subsequent call to this function.
-     *
-     * If damage is non-empty, then it may be assumed that any portion of the
-     * source buffer not covered by one of the rects has not been modified
-     * this frame. If damage is empty, then the whole source buffer must be
-     * treated as if it has been modified.
-     *
-     * If the layer's contents are not modified relative to the prior frame,
-     * damage must contain exactly one empty rect([0, 0, 0, 0]).
-     *
-     * The damage rects are relative to the pre-transformed buffer, and their
-     * origin is the top-left corner. They must not exceed the dimensions of
-     * the latched buffer.
-     *
-     * @param layer is the layer to which the damage region is set.
-     * @param damage is the new surface damage region.
-     */
-    SET_LAYER_SURFACE_DAMAGE = 0x302 << OPCODE_SHIFT,
-
-    // layer state commands (VALIDATE_DISPLAY required)
-
-    /**
-     * SET_LAYER_BLEND_MODE has this pseudo prototype
-     *
-     *   setLayerBlendMode(android.hardware.graphics.common.BlendMode mode)
-     *
-     * Sets the blend mode of the given layer.
-     *
-     * @param mode is the new blend mode.
-     */
-    SET_LAYER_BLEND_MODE = 0x400 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(Color color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color.
-     */
-    SET_LAYER_COLOR = 0x401 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COMPOSITION_TYPE has this pseudo prototype
-     *
-     *   setLayerCompositionType(Composition type);
-     *
-     * Sets the desired composition type of the given layer. During
-     * validateDisplay, the device may request changes to the composition
-     * types of any of the layers as described in the definition of
-     * Composition above.
-     *
-     * @param type is the new composition type.
-     */
-    SET_LAYER_COMPOSITION_TYPE = 0x402 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DATASPACE has this pseudo prototype
-     *
-     *   setLayerDataspace(android.hardware.graphics.common.Dataspace dataspace);
-     *
-     * Sets the dataspace of the layer.
-     *
-     * The dataspace provides more information about how to interpret the buffer
-     * or solid color, such as the encoding standard and color transform.
-     *
-     * See the values of Dataspace for more information.
-     *
-     * @param dataspace is the new dataspace.
-     */
-    SET_LAYER_DATASPACE = 0x403 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DISPLAY_FRAME has this pseudo prototype
-     *
-     *   setLayerDisplayFrame(Rect frame);
-     *
-     * Sets the display frame (the portion of the display covered by a layer)
-     * of the given layer. This frame must not exceed the display dimensions.
-     *
-     * @param frame is the new display frame.
-     */
-    SET_LAYER_DISPLAY_FRAME = 0x404 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PLANE_ALPHA has this pseudo prototype
-     *
-     *   setLayerPlaneAlpha(float alpha);
-     *
-     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
-     * which will be applied to the whole layer. It can be conceptualized as a
-     * preprocessing step which applies the following function:
-     *   if (blendMode == BlendMode::PREMULTIPLIED)
-     *       out.rgb = in.rgb * planeAlpha
-     *   out.a = in.a * planeAlpha
-     *
-     * If the device does not support this operation on a layer which is
-     * marked Composition::DEVICE, it must request a composition type change
-     * to Composition::CLIENT upon the next validateDisplay call.
-     *
-     * @param alpha is the plane alpha value to apply.
-     */
-    SET_LAYER_PLANE_ALPHA = 0x405 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SIDEBAND_STREAM has this pseudo prototype
-     *
-     *   setLayerSidebandStream(int streamIndex)
-     *
-     * Sets the sideband stream for this layer. If the composition type of the
-     * given layer is not Composition::SIDEBAND, this call must succeed and
-     * have no other effect.
-     *
-     * @param streamIndex is the new sideband stream.
-     */
-    SET_LAYER_SIDEBAND_STREAM = 0x406 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SOURCE_CROP has this pseudo prototype
-     *
-     *   setLayerSourceCrop(FRect crop);
-     *
-     * Sets the source crop (the portion of the source buffer which will fill
-     * the display frame) of the given layer. This crop rectangle must not
-     * exceed the dimensions of the latched buffer.
-     *
-     * If the device is not capable of supporting a true float source crop
-     * (i.e., it will truncate or round the floats to integers), it must set
-     * this layer to Composition::CLIENT when crop is non-integral for the
-     * most accurate rendering.
-     *
-     * If the device cannot support float source crops, but still wants to
-     * handle the layer, it must use the following code (or similar) to
-     * convert to an integer crop:
-     *   intCrop.left = (int) ceilf(crop.left);
-     *   intCrop.top = (int) ceilf(crop.top);
-     *   intCrop.right = (int) floorf(crop.right);
-     *   intCrop.bottom = (int) floorf(crop.bottom);
-     *
-     * @param crop is the new source crop.
-     */
-    SET_LAYER_SOURCE_CROP = 0x407 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_TRANSFORM has this pseudo prototype
-     *
-     * Sets the transform (rotation/flip) of the given layer.
-     *
-     *   setLayerTransform(Transform transform);
-     *
-     * @param transform is the new transform.
-     */
-    SET_LAYER_TRANSFORM = 0x408 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_VISIBLE_REGION has this pseudo prototype
-     *
-     *   setLayerVisibleRegion(Rect[] visible);
-     *
-     * Specifies the portion of the layer that is visible, including portions
-     * under translucent areas of other layers. The region is in screen space,
-     * and must not exceed the dimensions of the screen.
-     *
-     * @param visible is the new visible region, in screen space.
-     */
-    SET_LAYER_VISIBLE_REGION = 0x409 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_Z_ORDER has this pseudo prototype
-     *
-     *   setLayerZOrder(int z);
-     *
-     * Sets the desired Z order (height) of the given layer. A layer with a
-     * greater Z value occludes a layer with a lesser Z value.
-     *
-     * @param z is the new Z order.
-     */
-    SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT has this pseudo prototype
-     *
-     * setPresentOrValidateDisplayResult(int state);
-     *
-     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
-     * @param state is the state of present or validate
-     *    1 - Present Succeeded
-     *    0 - Validate succeeded
-     */
-    SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadata(long display, long layer,
-     *                            PerFrameMetadata[] data);
-     *
-     * Sets the PerFrameMetadata for the display. This metadata must be used
-     * by the implementation to better tone map content to that display.
-     *
-     * This is a method that may be called every frame. Thus it's
-     * implemented using buffered transport.
-     * SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
-     * mechanism.
-     */
-    SET_LAYER_PER_FRAME_METADATA = 0x303 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_FLOAT_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(FloatColor color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color using float type.
-     */
-    SET_LAYER_FLOAT_COLOR = 0x40c << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setLayerColorTransform(float[16] matrix);
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 16 * 4: matrix
-     *
-     * Sets a matrix for color transform which will be applied on this layer
-     * before composition.
-     *
-     * If the device is not capable of apply the matrix on this layer, it must force
-     * this layer to client composition during VALIDATE_DISPLAY.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in],
-     * the input color must first be converted to linear space
-     * [R_linear, G_linear, B_linear], then the output linear color
-     * [R_out_linear, G_out_linear, B_out_linear] will be:
-     *
-     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
-     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
-     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
-     *
-     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
-     * gamma space: [R_out, G_out, B_out] before blending.
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     */
-
-    SET_LAYER_COLOR_TRANSFORM = 0x40d << OPCODE_SHIFT,
-    /*
-     * SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadataBlobs(long display, long layer,
-     *                                   PerFrameMetadataBlob[] metadata);
-     *
-     *   This command sends metadata that may be used for tone-mapping the
-     *   associated layer.  The metadata structure follows a {key, blob}
-     *   format (see the PerFrameMetadataBlob struct).  All keys must be
-     *   returned by a prior call to getPerFrameMetadataKeys and must
-     *   be part of the list of keys associated with blob-type metadata
-     *   (see PerFrameMetadataKey).
-     *
-     *   This method may be called every frame.
-     */
-    SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET_PROPERTY has this pseudo prototype
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 3: clientTargetProperty.pixelFormat
-     *     4 - 7: clientTargetProperty.dataspace
-     *     8 - 11: whitePointNits
-     *
-     * The white point parameter describes the intended white point of the client target buffer.
-     * When client composition blends both HDR and SDR content, the client must composite to the
-     * brightness space as specified by the hardware composer. This is so that adjusting the real
-     * display brightness may be applied atomically with compensating the client target output. For
-     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
-     * the SDR buffers when an HDR layer is simultaneously device-composited.
-     *
-     *   setClientTargetProperty(ClientTargetProperty clientTargetProperty, float whitePointNits);
-     */
-    SET_CLIENT_TARGET_PROPERTY = 0x105 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_GENERIC_METADATA has this pseudo prototype
-     *
-     *   setLayerGenericMetadata(string key, bool mandatory, byte[] value);
-     *
-     * Sets a piece of generic metadata for the given layer. If this
-     * function is called twice with the same key but different values, the
-     * newer value must override the older one. Calling this function with a
-     * 0-length value must reset that key's metadata as if it had not been
-     * set.
-     *
-     * A given piece of metadata may either be mandatory or a hint
-     * (non-mandatory) as indicated by the second parameter. Mandatory
-     * metadata may affect the composition result, which is to say that it
-     * may cause a visible change in the final image. By contrast, hints may
-     * only affect the composition strategy, such as which layers are
-     * composited by the client, but must not cause a visible change in the
-     * final image. The value of the mandatory flag shall match the value
-     * returned from getLayerGenericMetadataKeys for the given key.
-     *
-     * Only keys which have been returned from getLayerGenericMetadataKeys()
-     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
-     *
-     * The value passed into this function shall be the binary
-     * representation of a HIDL type corresponding to the given key. For
-     * example, a key of 'com.example.V1_3.Foo' shall be paired with a
-     * value of type com.example@1.3::Foo, which would be defined in a
-     * vendor HAL extension.
-     *
-     * This function will be encoded in the command buffer in this order:
-     *   1) The key length, stored as a uint32_t
-     *   2) The key itself, padded to a uint32_t boundary if necessary
-     *   3) The mandatory flag, stored as a uint32_t
-     *   4) The value length in bytes, stored as a uint32_t
-     *   5) The value itself, padded to a uint32_t boundary if necessary
-     *
-     * @param key indicates which metadata value should be set on this layer
-     * @param mandatory indicates whether this particular key represents
-     *        mandatory metadata or a hint (non-mandatory metadata), as
-     *        described above
-     * @param value is a binary representation of a HIDL struct
-     *        corresponding to the key as described above
-     */
-    SET_LAYER_GENERIC_METADATA = 0x40e << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_WHITE_POINT_NITS has this pseudo prototype
-     *
-     *   setLayerWhitePointNits(float sdrWhitePointNits);
-     *
-     * Sets the desired white point for the layer. This is intended to be used when presenting
-     * an SDR layer alongside HDR content. The HDR content will be presented at the display
-     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
-     * provided.
-     *
-     * @param whitePointNits is the white point in nits.
-     */
-    SET_LAYER_WHITE_POINT_NITS = 0x305 << OPCODE_SHIFT,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
deleted file mode 100644
index 4b3d31a..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ /dev/null
@@ -1,37 +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.graphics.composer3;
-
-/**
- * Display requests returned by getDisplayRequests.
- */
-@VintfStability
-@Backing(type="int")
-enum DisplayRequest {
-    /**
-     * Instructs the client to provide a new client target buffer, even if
-     * no layers are marked for client composition.
-     */
-    FLIP_CLIENT_TARGET = 1 << 0,
-    /**
-     * Instructs the client to write the result of client composition
-     * directly into the virtual display output buffer. If any of the
-     * layers are not marked as Composition::CLIENT or the given display
-     * is not a virtual display, this request has no effect.
-     */
-    WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
deleted file mode 100644
index f67c3ce..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ /dev/null
@@ -1,36 +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.graphics.composer3;
-
-/**
- * Output parameters for IComposerClient.executeCommands
- */
-@VintfStability
-parcelable ExecuteCommandsStatus {
-    /**
-     * Indicates whether the output command message queue has changed.
-     */
-    boolean queueChanged;
-    /**
-     * Indicates whether the output command message queue has changed.
-     */
-    int length;
-    /**
-     * An array of handles referenced by the output commands.
-     */
-    android.hardware.common.NativeHandle[] handles;
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 230980d..f661f8b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -16,11 +16,8 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.common.fmq.MQDescriptor;
-import android.hardware.common.fmq.SynchronizedReadWrite;
 import android.hardware.graphics.composer3.ClientTargetProperty;
 import android.hardware.graphics.composer3.ColorMode;
-import android.hardware.graphics.composer3.Command;
 import android.hardware.graphics.composer3.ContentType;
 import android.hardware.graphics.composer3.DisplayAttribute;
 import android.hardware.graphics.composer3.DisplayCapability;
@@ -28,7 +25,6 @@
 import android.hardware.graphics.composer3.DisplayContentSample;
 import android.hardware.graphics.composer3.DisplayContentSamplingAttributes;
 import android.hardware.graphics.composer3.DisplayIdentification;
-import android.hardware.graphics.composer3.ExecuteCommandsStatus;
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
@@ -40,6 +36,8 @@
 import android.hardware.graphics.composer3.VirtualDisplay;
 import android.hardware.graphics.composer3.VsyncPeriodChangeConstraints;
 import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
+import android.hardware.graphics.composer3.command.CommandPayload;
+import android.hardware.graphics.composer3.command.CommandResultPayload;
 
 @VintfStability
 interface IComposerClient {
@@ -159,23 +157,13 @@
     void destroyVirtualDisplay(long display);
 
     /**
-     * Executes commands from the input command message queue. Return values
-     * generated by the input commands are written to the output command
-     * message queue in the form of value commands.
+     * Executes commands.
      *
-     * @param inLength is the length of input commands.
-     * @param inHandles is an array of handles referenced by the input
-     *        commands.
+     * @param commands are the commands to be processed.
      *
-     * @return is the status of the command.
-
-     * @exception EX_BAD_PARAMETER when inLength is not equal to the length of
-     *                       commands in the input command message queue.
-     * @exception NO_RESOURCES when the output command message queue was not
-     *                      properly drained.
+     * @return are the command statuses.
      */
-    ExecuteCommandsStatus executeCommands(
-            int inLength, in android.hardware.common.NativeHandle[] inHandles);
+    CommandResultPayload[] executeCommands(in CommandPayload[] commands);
 
     /**
      * Retrieves which display configuration is currently active.
@@ -436,17 +424,6 @@
     int getMaxVirtualDisplayCount();
 
     /**
-     * Gets the output command message queue.
-     *
-     * This function must only be called inside executeCommands closure.
-     *
-     * @return is the descriptor of the output command queue.
-     *
-     * @exception EX_NO_RESOURCES when failed to get the queue temporarily.
-     */
-    MQDescriptor<int, SynchronizedReadWrite> getOutputCommandQueue();
-
-    /**
      * Returns the PerFrameMetadataKeys that are supported by this device.
      *
      * @param display is the display on which to create the layer.
@@ -732,14 +709,6 @@
             long display, boolean enable, FormatColorComponent componentMask, long maxFrames);
 
     /**
-     * Sets the input command message queue.
-     *
-     * @param descriptor is the descriptor of the input command message queue.
-     * @exception EX_NO_RESOURCES when failed to set the queue temporarily.
-     */
-    void setInputCommandQueue(in MQDescriptor<int, SynchronizedReadWrite> descriptor);
-
-    /**
      * Sets the power mode of the given display. The transition must be
      * complete when this function returns. It is valid to call this function
      * multiple times with the same power mode.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index b666e6a..3962920 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -16,8 +16,6 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.graphics.composer3.PerFrameMetadataKey;
-
 /**
  * PerFrameMetadataKey
  *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
new file mode 100644
index 0000000..3a08d3b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+
+@VintfStability
+parcelable Buffer {
+    /**
+     * Buffer slot in the range [0, bufferSlotCount) where bufferSlotCount is
+     * the parameter used when the layer was created.
+     * @see IComposer.createLayer.
+     * The slot is used as a buffer caching mechanism. When the Buffer.handle
+     * is null, the implementation uses the previous buffer associated with this
+     * slot.
+     */
+    int slot;
+
+    /**
+     * Buffer Handle. Can be null if this is the same buffer that was sent
+     * previously on this slot.
+     */
+    @nullable NativeHandle handle;
+
+    /**
+     * Buffer fence that represents when it is safe to access the buffer.
+     * A null fence indicates that the buffer can be accessed immediately.
+     */
+    @nullable ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
new file mode 100644
index 0000000..3800eff
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.Composition;
+
+@VintfStability
+parcelable ChangedCompositionTypes {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    @VintfStability
+    parcelable Layer {
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+
+        /**
+         * The new composition type.
+         */
+        Composition composition;
+    }
+
+    /**
+     * Indicates which layers has composition changes
+     */
+    Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
index c6fd063..d8d45a1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -14,25 +14,26 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.Dataspace;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.command.Buffer;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ClientTarget {
     /**
-     * colorOut = colorSrc
+     * Client target Buffer
      */
-    NONE = 1,
+    Buffer buffer;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The dataspace of the buffer, as described in LayerCommand.dataspace.
      */
-    PREMULTIPLIED = 2,
+    Dataspace dataspace;
+
     /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
+     * The surface damage regions.
      */
-    COVERAGE = 3,
+    Rect[] damage;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
new file mode 100644
index 0000000..c80e4ce
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.ClientTargetProperty;
+
+@VintfStability
+parcelable ClientTargetPropertyWithNits {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The Client target property.
+     */
+    ClientTargetProperty clientTargetProperty;
+
+    /**
+     * The white points nits as described in CommandResultPayload.clientTargetProperty
+     */
+    float whitePointNits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index c6fd063..9cc8fa7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -14,25 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.ColorTransform;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ColorTransformPayload {
     /**
-     * colorOut = colorSrc
+     * 4x4 transform matrix (16 floats) as described in DisplayCommand.colorTransform.
      */
-    NONE = 1,
+    float[] matrix;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * Hint value which may be used instead of the given matrix unless it
+     * is ColorTransform::ARBITRARY.
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
index c6fd063..c1555e6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -14,25 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.DisplayCommand;
+import android.hardware.graphics.composer3.command.LayerCommand;
 
 /**
- * Blend modes, settable per layer.
+ * Type of commands that can be used in IComposerClient.executeCommands.
+ * Note that this is a union and each command can only have one type.
  */
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
-    /**
-     * colorOut = colorSrc
-     */
-    NONE = 1,
-    /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
-     */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+union CommandPayload {
+    DisplayCommand displayCommand;
+    LayerCommand layerCommand;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
new file mode 100644
index 0000000..b6086ca
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.ChangedCompositionTypes;
+import android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits;
+import android.hardware.graphics.composer3.command.DisplayRequest;
+import android.hardware.graphics.composer3.command.Error;
+import android.hardware.graphics.composer3.command.PresentFence;
+import android.hardware.graphics.composer3.command.PresentOrValidate;
+import android.hardware.graphics.composer3.command.ReleaseFences;
+
+@VintfStability
+union CommandResultPayload {
+    /**
+     * Indicates an error generated by a command.
+     */
+    Error error;
+
+    /**
+     * Sets the layers for which the device requires a different composition
+     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
+     * client must either update its state with these types and call
+     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
+     * the display again.
+     */
+    ChangedCompositionTypes changedCompositionType;
+
+    /**
+     * Sets the display requests and the layer requests required for the last
+     * validated configuration.
+     *
+     * Display requests provide information about how the client must handle
+     * the client target. Layer requests provide information about how the
+     * client must handle an individual layer.
+     */
+    DisplayRequest displayRequest;
+
+    /**
+     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
+     * displays, this fence must be signaled at the vsync when the result
+     * of composition of this frame starts to appear (for video-mode panels)
+     * or starts to transfer to panel memory (for command-mode panels). For
+     * virtual displays, this fence must be signaled when writes to the output
+     * buffer have completed and it is safe to read from it.
+     */
+    PresentFence presentFence;
+
+    /**
+     * Sets the release fences for device layers on this display which will
+     * receive new buffer contents this frame.
+     *
+     * A release fence is a file descriptor referring to a sync fence object
+     * which must be signaled after the device has finished reading from the
+     * buffer presented in the prior frame. This indicates that it is safe to
+     * start writing to the buffer again. If a given layer's fence is not
+     * returned from this function, it must be assumed that the buffer
+     * presented on the previous frame is ready to be written.
+     *
+     * The fences returned by this function must be unique for each layer
+     * (even if they point to the same underlying sync object).
+     *
+     */
+    ReleaseFences releaseFences;
+
+    /**
+     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
+     */
+    PresentOrValidate presentOrValidateResult;
+
+    /**
+     * The white point parameter describes the intended white point of the client target buffer.
+     * When client composition blends both HDR and SDR content, the client must composite to the
+     * brightness space as specified by the hardware composer. This is so that adjusting the real
+     * display brightness may be applied atomically with compensating the client target output. For
+     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
+     * the SDR buffers when an HDR layer is simultaneously device-composited.
+     */
+    ClientTargetPropertyWithNits clientTargetProperty;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
new file mode 100644
index 0000000..7295ada
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -0,0 +1,151 @@
+/**
+ * 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.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.ClientTarget;
+import android.hardware.graphics.composer3.command.ColorTransformPayload;
+
+@VintfStability
+parcelable DisplayCommand {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * Sets a color transform which will be applied after composition.
+     *
+     * If hint is not ColorTransform::ARBITRARY, then the device may use the
+     * hint to apply the desired color transform instead of using the color
+     * matrix directly.
+     *
+     * If the device is not capable of either using the hint or the matrix to
+     * apply the desired color transform, it must force all layers to client
+     * composition during VALIDATE_DISPLAY.
+     *
+     * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
+     * the client must never apply the color transform during client
+     * composition, even if all layers are being composed by the client.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
+     * output color [R_out, G_out, B_out] will be:
+     *
+     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+     *
+     */
+    @nullable ColorTransformPayload colorTransform;
+
+    /**
+     * Sets the buffer handle which will receive the output of client
+     * composition.  Layers marked as Composition::CLIENT must be composited
+     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
+     * marked as Composition::CLIENT must be composited with this buffer by
+     * the device.
+     *
+     * The buffer handle provided may be empty if no layers are being
+     * composited by the client. This must not result in an error (unless an
+     * invalid display handle is also provided).
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the client
+     * target buffer.  If it is already safe to read from this buffer, an
+     * empty handle may be passed instead.
+     *
+     * For more about dataspaces, see SET_LAYER_DATASPACE.
+     *
+     * The damage parameter describes a surface damage region as defined in
+     * the description of SET_LAYER_SURFACE_DAMAGE.
+     *
+     * Will be called before PRESENT_DISPLAY if any of the layers are marked
+     * as Composition::CLIENT. If no layers are so marked, then it is not
+     * necessary to call this function. It is not necessary to call
+     * validateDisplay after changing the target through this function.
+     */
+    @nullable ClientTarget clientTarget;
+
+    /**
+     * Sets the output buffer for a virtual display. That is, the buffer to
+     * which the composition result will be written.
+     *
+     * Also provides a file descriptor referring to a release sync fence
+     * object, which must be signaled when it is safe to write to the output
+     * buffer. If it is already safe to write to the output buffer, an empty
+     * handle may be passed instead.
+     *
+     * Must be called at least once before PRESENT_DISPLAY, but does not have
+     * any interaction with layer state or display validation.
+     */
+    @nullable Buffer virtualDisplayOutputBuffer;
+
+    /**
+     * Instructs the device to inspect all of the layer state and determine if
+     * there are any composition type changes necessary before presenting the
+     * display. Permitted changes are described in the definition of
+     * Composition above.
+     */
+    boolean validateDisplay;
+
+    /**
+     * Accepts the changes required by the device from the previous
+     * validateDisplay call (which may be queried using
+     * getChangedCompositionTypes) and revalidates the display. This function
+     * is equivalent to requesting the changed types from
+     * getChangedCompositionTypes, setting those types on the corresponding
+     * layers, and then calling validateDisplay again.
+     *
+     * After this call it must be valid to present this display. Calling this
+     * after validateDisplay returns 0 changes must succeed with NONE, but
+     * must have no other effect.
+     */
+    boolean acceptDisplayChanges;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer).
+     *
+     * Prior to calling this function, the display must be successfully
+     * validated with validateDisplay. Note that setLayerBuffer and
+     * setLayerSurfaceDamage specifically do not count as layer state, so if
+     * there are no other changes to the layer state (or to the buffer's
+     * properties as described in setLayerBuffer), then it is safe to call
+     * this function without first validating the display.
+     */
+    boolean presentDisplay;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer) if validate can be skipped,
+     * or perform a VALIDATE_DISPLAY action instead.
+     */
+    boolean presentOrValidateDisplay;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
new file mode 100644
index 0000000..10bd10c
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+@VintfStability
+parcelable DisplayRequest {
+    /**
+     * Instructs the client to provide a new client target buffer, even if
+     * no layers are marked for client composition.
+     */
+    const int FLIP_CLIENT_TARGET = 1 << 0;
+
+    /**
+     * Instructs the client to write the result of client composition
+     * directly into the virtual display output buffer. If any of the
+     * layers are not marked as Composition::CLIENT or the given display
+     * is not a virtual display, this request has no effect.
+     */
+    const int WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1;
+
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The display requests for the current validated state. This must be a
+     * bitwise-or of the constants in `DisplayRequest`.
+     */
+    int mask;
+
+    @VintfStability
+    parcelable LayerRequest {
+        /**
+         * The client must clear its target with transparent pixels where
+         * this layer would be. The client may ignore this request if the
+         * layer must be blended.
+         */
+        const int CLEAR_CLIENT_TARGET = 1 << 0;
+
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+        /**
+         * The layer requests for the current validated state. This must be a
+         * bitwise-or of the constants in `LayerRequest`.
+         */
+        int mask;
+    }
+
+    /**
+     * The layer requests for the current validated state.
+     */
+    LayerRequest[] layerRequests;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
index c6fd063..19843b9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
@@ -14,25 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable Error {
     /**
-     * colorOut = colorSrc
+     * The index in the command payload array.
      */
-    NONE = 1,
+    int commandIndex;
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The error generated by the command. Can be one of the IComposerClient.EX_*
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    int errorCode;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index c6fd063..a4e1fe8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -14,25 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.composer3.LayerGenericMetadataKey;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable GenericMetadata {
     /**
-     * colorOut = colorSrc
+     * Indicates which metadata value should be set.
      */
-    NONE = 1,
+    LayerGenericMetadataKey key;
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The binary representation of a AIDL struct corresponding to
+     * the key as described above.
+     * TODO(b/209691612): revisit the use of byte[]
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    byte[] value;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..eac051b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,301 @@
+/**
+ * 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.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.graphics.common.FRect;
+import android.hardware.graphics.common.Point;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.Color;
+import android.hardware.graphics.composer3.FloatColor;
+import android.hardware.graphics.composer3.PerFrameMetadata;
+import android.hardware.graphics.composer3.PerFrameMetadataBlob;
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.GenericMetadata;
+import android.hardware.graphics.composer3.command.ParcelableBlendMode;
+import android.hardware.graphics.composer3.command.ParcelableComposition;
+import android.hardware.graphics.composer3.command.ParcelableDataspace;
+import android.hardware.graphics.composer3.command.ParcelableTransform;
+import android.hardware.graphics.composer3.command.PlaneAlpha;
+import android.hardware.graphics.composer3.command.WhitePointNits;
+import android.hardware.graphics.composer3.command.ZOrder;
+
+@VintfStability
+parcelable LayerCommand {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The layer which this commands refers to.
+     * @see IComposer.createLayer
+     */
+    long layer;
+
+    /**
+     * Asynchronously sets the position of a cursor layer.
+     *
+     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
+     * If validation succeeds (i.e., the device does not request a composition
+     * change for that layer), then once a buffer has been set for the layer
+     * and it has been presented, its position may be set by this function at
+     * any time between presentDisplay and any subsequent validateDisplay
+     * calls for this display.
+     *
+     * Once validateDisplay is called, this function must not be called again
+     * until the validate/present sequence is completed.
+     *
+     * May be called from any thread so long as it is not interleaved with the
+     * validate/present sequence as described above.
+     */
+    @nullable Point cursorPosition;
+
+    /**
+     * Sets the buffer handle to be displayed for this layer. If the buffer
+     * properties set at allocation time (width, height, format, and usage)
+     * have not changed since the previous frame, it is not necessary to call
+     * validateDisplay before calling presentDisplay unless new state needs to
+     * be validated in the interim.
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the given
+     * buffer. If it is already safe to read from the buffer, an empty handle
+     * may be passed instead.
+     *
+     * This function must return NONE and have no other effect if called for a
+     * layer with a composition type of Composition::SOLID_COLOR (because it
+     * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
+     * synchronization and buffer updates for these layers are handled
+     * elsewhere).
+     */
+    @nullable Buffer buffer;
+
+    /**
+     * Provides the region of the source buffer which has been modified since
+     * the last frame. This region does not need to be validated before
+     * calling presentDisplay.
+     *
+     * Once set through this function, the damage region remains the same
+     * until a subsequent call to this function.
+     *
+     * If damage is non-empty, then it may be assumed that any portion of the
+     * source buffer not covered by one of the rects has not been modified
+     * this frame. If damage is empty, then the whole source buffer must be
+     * treated as if it has been modified.
+     *
+     * If the layer's contents are not modified relative to the prior frame,
+     * damage must contain exactly one empty rect([0, 0, 0, 0]).
+     *
+     * The damage rects are relative to the pre-transformed buffer, and their
+     * origin is the top-left corner. They must not exceed the dimensions of
+     * the latched buffer.
+     */
+    @nullable Rect[] damage;
+
+    /**
+     * Sets the blend mode of the given layer.
+     */
+    @nullable ParcelableBlendMode blendMode;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition::SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable Color color;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition::SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable FloatColor floatColor;
+
+    /**
+     * Sets the desired composition type of the given layer. During
+     * validateDisplay, the device may request changes to the composition
+     * types of any of the layers as described in the definition of
+     * Composition above.
+     */
+    @nullable ParcelableComposition composition;
+
+    /**
+     * Sets the dataspace of the layer.
+     *
+     * The dataspace provides more information about how to interpret the buffer
+     * or solid color, such as the encoding standard and color transform.
+     *
+     * See the values of ParcelableDataspace for more information.
+     */
+    @nullable ParcelableDataspace dataspace;
+
+    /**
+     * Sets the display frame (the portion of the display covered by a layer)
+     * of the given layer. This frame must not exceed the display dimensions.
+     */
+    @nullable Rect displayFrame;
+
+    /**
+     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to the whole layer. It can be conceptualized as a
+     * preprocessing step which applies the following function:
+     *   if (blendMode == BlendMode::PREMULTIPLIED)
+     *       out.rgb = in.rgb * planeAlpha
+     *   out.a = in.a * planeAlpha
+     *
+     * If the device does not support this operation on a layer which is
+     * marked Composition::DEVICE, it must request a composition type change
+     * to Composition::CLIENT upon the next validateDisplay call.
+     *
+     */
+    @nullable PlaneAlpha planeAlpha;
+
+    /**
+     * Sets the sideband stream for this layer. If the composition type of the
+     * given layer is not Composition::SIDEBAND, this call must succeed and
+     * have no other effect.
+     */
+    @nullable NativeHandle sidebandStream;
+
+    /**
+     * Sets the source crop (the portion of the source buffer which will fill
+     * the display frame) of the given layer. This crop rectangle must not
+     * exceed the dimensions of the latched buffer.
+     *
+     * If the device is not capable of supporting a true float source crop
+     * (i.e., it will truncate or round the floats to integers), it must set
+     * this layer to Composition::CLIENT when crop is non-integral for the
+     * most accurate rendering.
+     *
+     * If the device cannot support float source crops, but still wants to
+     * handle the layer, it must use the following code (or similar) to
+     * convert to an integer crop:
+     *   intCrop.left = (int) ceilf(crop.left);
+     *   intCrop.top = (int) ceilf(crop.top);
+     *   intCrop.right = (int) floorf(crop.right);
+     *   intCrop.bottom = (int) floorf(crop.bottom);
+     */
+    @nullable FRect sourceCrop;
+
+    /**
+     * Sets the transform (rotation/flip) of the given layer.
+     */
+    @nullable ParcelableTransform transform;
+
+    /**
+     * Specifies the portion of the layer that is visible, including portions
+     * under translucent areas of other layers. The region is in screen space,
+     * and must not exceed the dimensions of the screen.
+     */
+    @nullable Rect[] visibleRegion;
+
+    /**
+     * Sets the desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     */
+    @nullable ZOrder z;
+
+    /**
+     * Sets a matrix for color transform which will be applied on this layer
+     * before composition.
+     *
+     * If the device is not capable of apply the matrix on this layer, it must force
+     * this layer to client composition during VALIDATE_DISPLAY.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in],
+     * the input color must first be converted to linear space
+     * [R_linear, G_linear, B_linear], then the output linear color
+     * [R_out_linear, G_out_linear, B_out_linear] will be:
+     *
+     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
+     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
+     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
+     *
+     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
+     * gamma space: [R_out, G_out, B_out] before blending.
+     */
+    @nullable float[] colorTransform;
+
+    /**
+     * Sets the desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     */
+    @nullable WhitePointNits whitePointNits;
+
+    /**
+     * Sets a piece of generic metadata for the given layer. If this
+     * function is called twice with the same key but different values, the
+     * newer value must override the older one. Calling this function with a
+     * 0-length value must reset that key's metadata as if it had not been
+     * set.
+     *
+     * A given piece of metadata may either be mandatory or a hint
+     * (non-mandatory) as indicated by the second parameter. Mandatory
+     * metadata may affect the composition result, which is to say that it
+     * may cause a visible change in the final image. By contrast, hints may
+     * only affect the composition strategy, such as which layers are
+     * composited by the client, but must not cause a visible change in the
+     * final image. The value of the mandatory flag shall match the value
+     * returned from getLayerGenericMetadataKeys for the given key.
+     *
+     * Only keys which have been returned from getLayerGenericMetadataKeys()
+     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
+     *
+     * The value passed into this function shall be the binary
+     * representation of a stable AIDL type corresponding to the given key. For
+     * example, a key of 'com.example.Foo-V2' shall be paired with a
+     * value of type com.exampleFoo-V2, which would be defined in a
+     * vendor HAL extension.
+     */
+    @nullable GenericMetadata genericMetadata;
+
+    /**
+     * Sets the PerFrameMetadata for the display. This metadata must be used
+     * by the implementation to better tone map content to that display.
+     *
+     * This is a command that may be called every frame.
+     */
+    @nullable PerFrameMetadata[] perFrameMetadata;
+
+    /**
+     * This command sends metadata that may be used for tone-mapping the
+     * associated layer.  The metadata structure follows a {key, blob}
+     * format (see the PerFrameMetadataBlob struct).  All keys must be
+     * returned by a prior call to getPerFrameMetadataKeys and must
+     * be part of the list of keys associated with blob-type metadata
+     * (see PerFrameMetadataKey).
+     *
+     * This command may be called every frame.
+     */
+    @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 65%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 7f385de..f912853 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
+/**
+ * Copyright (c) 2021, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.common.BlendMode;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+parcelable ParcelableBlendMode {
+    BlendMode blendMode;
 }
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 64%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 7f385de..91979d8 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
+/**
+ * Copyright (c) 2021, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.Composition;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+parcelable ParcelableComposition {
+    Composition composition;
 }
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 65%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 7f385de..6be750d 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
+/**
+ * Copyright (c) 2021, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.common.Dataspace;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+parcelable ParcelableDataspace {
+    Dataspace dataspace;
 }
diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 65%
copy from radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 7f385de..910d014 100644
--- a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
+/**
+ * Copyright (c) 2021, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.radio;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.common.Transform;
 
 @VintfStability
-@Backing(type="int")
-enum SapTransferProtocol {
-    T0,
-    T1,
+parcelable ParcelableTransform {
+    Transform transform;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index 10de558..fa1889b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PlaneAlpha {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * An alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to a whole layer.
+     * @see LayerCommand.planeAlpha
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    float alpha;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
index c6fd063..0c14406 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -14,25 +14,18 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable PresentFence {
     /**
-     * colorOut = colorSrc
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    NONE = 1,
+    long display;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The present fence for this display.
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index c6fd063..7fc60c4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -14,25 +14,19 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable PresentOrValidate {
     /**
-     * colorOut = colorSrc
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    NONE = 1,
+    long display;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * Whether PresentOrValidate presented or validated the display.
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    @VintfStability enum Result { Presented, Validated }
+    Result result;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
new file mode 100644
index 0000000..762f5eb
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+@VintfStability
+parcelable ReleaseFences {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+    @VintfStability
+    parcelable Layer {
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+
+        /**
+         * The release fence for this layer.
+         */
+        ParcelFileDescriptor fence;
+    }
+
+    /**
+     * The layers which has release fences.
+     */
+    Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
new file mode 100644
index 0000000..ec46cdf
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -0,0 +1,29 @@
+/**
+ * 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.graphics.composer3.command;
+
+@VintfStability
+parcelable WhitePointNits {
+    /**
+     * The desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     * @see LayerCommand.whitePointNits.
+     */
+    float nits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
index 10de558..68120b0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable ZOrder {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     * @see LayerCommand.z;
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
index d59190d..5bda15a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
@@ -74,25 +74,25 @@
 static_assert(aidl::android::hardware::graphics::composer3::Capability::SKIP_VALIDATE ==
               static_cast<aidl::android::hardware::graphics::composer3::Capability>(4));
 
-static_assert(aidl::android::hardware::graphics::composer3::LayerRequest::CLEAR_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::LayerRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::LayerRequest::
-                              CLEAR_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::LayerRequest::
+                      CLEAR_CLIENT_TARGET ==
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       LayerRequest::CLEAR_CLIENT_TARGET));
 
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::INVALID ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::INVALID ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               INVALID));
 static_assert(
-        aidl::android::hardware::graphics::composer3::BlendMode::NONE ==
-        static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+        aidl::android::hardware::graphics::common::BlendMode::NONE ==
+        static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                 ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::NONE));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::PREMULTIPLIED ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::PREMULTIPLIED ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               PREMULTIPLIED));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::COVERAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::COVERAGE ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               COVERAGE));
 
@@ -121,15 +121,14 @@
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::Composition::
                               SIDEBAND));
 
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::FLIP_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::FLIP_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::
+static_assert(
+        aidl::android::hardware::graphics::composer3::command::DisplayRequest::FLIP_CLIENT_TARGET ==
+        static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                 DisplayRequest::FLIP_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::
                       WRITE_CLIENT_TARGET_TO_OUTPUT ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
 
 static_assert(aidl::android::hardware::graphics::composer3::HandleIndex::EMPTY ==
               static_cast<aidl::android::hardware::graphics::composer3::HandleIndex>(
@@ -188,162 +187,6 @@
                 ::android::hardware::graphics::composer::V2_4::IComposerClient::DisplayCapability::
                         AUTO_LOW_LATENCY_MODE));
 
-static_assert(aidl::android::hardware::graphics::composer3::Command::LENGTH_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              LENGTH_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_SHIFT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_SHIFT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_LAYER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_LAYER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_ERROR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_ERROR));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_CHANGED_COMPOSITION_TYPES ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_CHANGED_COMPOSITION_TYPES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_DISPLAY_REQUESTS ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_DISPLAY_REQUESTS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_PRESENT_FENCE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_FENCE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_RELEASE_FENCES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_RELEASE_FENCES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_COLOR_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_OUTPUT_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_OUTPUT_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::ACCEPT_DISPLAY_CHANGES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              ACCEPT_DISPLAY_CHANGES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_OR_VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_OR_VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_CURSOR_POSITION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_CURSOR_POSITION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SURFACE_DAMAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SURFACE_DAMAGE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BLEND_MODE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BLEND_MODE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COMPOSITION_TYPE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COMPOSITION_TYPE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DATASPACE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DATASPACE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DISPLAY_FRAME ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DISPLAY_FRAME));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PLANE_ALPHA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PLANE_ALPHA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SIDEBAND_STREAM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SIDEBAND_STREAM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SOURCE_CROP ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SOURCE_CROP));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_VISIBLE_REGION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_VISIBLE_REGION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_Z_ORDER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_Z_ORDER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::
-                      SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PER_FRAME_METADATA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_FLOAT_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_FLOAT_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR_TRANSFORM));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_LAYER_PER_FRAME_METADATA_BLOBS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET_PROPERTY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET_PROPERTY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_GENERIC_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_GENERIC_METADATA));
-
 static_assert(aidl::android::hardware::graphics::composer3::DisplayAttribute::INVALID ==
               static_cast<aidl::android::hardware::graphics::composer3::DisplayAttribute>(
                       ::android::hardware::graphics::composer::V2_4::IComposerClient::Attribute::
@@ -612,4 +455,4 @@
     return true;
 }
 
-}  // namespace android::h2a
\ No newline at end of file
+}  // namespace android::h2a
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 420b32c..741572d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -19,7 +19,7 @@
     // 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
+    // SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
@@ -28,16 +28,39 @@
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
+        // Needed for librenderengine
+        "skia_deps",
     ],
     srcs: [
         "VtsHalGraphicsComposer3_TargetTest.cpp",
+        "VtsHalGraphicsComposer3_ReadbackTest.cpp",
         "composer-vts/GraphicsComposerCallback.cpp",
     ],
 
-    // TODO(b/64437680): Assume these libs are always available on the device.
     shared_libs: [
+        "libEGL",
+        "libGLESv1_CM",
+        "libGLESv2",
         "libbinder_ndk",
         "libbinder",
+        "libfmq",
+        "libbase",
+        "libsync",
+        "libui",
+        "libgui",
+        "libhidlbase",
+        "libprocessgroup",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
+        "libvndksupport",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
@@ -45,9 +68,23 @@
         "android.hardware.graphics.common@1.2",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
         "android.hardware.graphics.composer@3-vts",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@2.1-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+        "libaidlcommonsupport",
+        "libgtest",
+        "librenderengine",
+        "libshaders",
+        "libtonemap",
     ],
-
+    cflags: [
+        "-Wconversion",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
new file mode 100644
index 0000000..717b60c
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -0,0 +1,1329 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "graphics_composer_aidl_hal_readback_tests@3"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <android/binder_manager.h>
+#include <composer-vts/include/ReadbackVts.h>
+#include <composer-vts/include/RenderEngineVts.h>
+#include <gtest/gtest.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include "composer-vts/include/GraphicsComposerCallback.h"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+namespace {
+
+using ::android::Rect;
+using common::Dataspace;
+using common::PixelFormat;
+
+class GraphicsCompositionTestBase : public ::testing::Test {
+  protected:
+    void SetUpBase(const std::string& name) {
+        ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
+        ASSERT_NE(binder, nullptr);
+        ASSERT_NO_FATAL_FAILURE(mComposer = IComposer::fromBinder(binder));
+        ASSERT_NE(mComposer, nullptr);
+        ASSERT_NO_FATAL_FAILURE(mComposer->createClient(&mComposerClient));
+        mComposerCallback = ::ndk::SharedRefBase::make<GraphicsComposerCallback>();
+        mComposerClient->registerCallback(mComposerCallback);
+
+        // assume the first display is primary and is never removed
+        mPrimaryDisplay = waitForFirstDisplay();
+
+        ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
+        int32_t activeConfig;
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                  DisplayAttribute::WIDTH, &mDisplayWidth)
+                            .isOk());
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                  DisplayAttribute::HEIGHT, &mDisplayHeight)
+                            .isOk());
+
+        setTestColorModes();
+
+        // explicitly disable vsync
+        EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
+        mComposerCallback->setVsyncAllowed(false);
+
+        // set up gralloc
+        mGraphicBuffer = allocate();
+
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+
+        ASSERT_NO_FATAL_FAILURE(
+                mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
+                        ::android::renderengine::RenderEngineCreationArgs::Builder()
+                                .setPixelFormat(static_cast<int>(common::PixelFormat::RGBA_8888))
+                                .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
+                                .setUseColorManagerment(true)
+                                .setEnableProtectedContext(false)
+                                .setPrecacheToneMapperShaderOnly(false)
+                                .setContextPriority(::android::renderengine::RenderEngine::
+                                                            ContextPriority::HIGH)
+                                .build())));
+
+        ::android::renderengine::DisplaySettings clientCompositionDisplay;
+        clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
+        clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
+
+        mTestRenderEngine->initGraphicBuffer(
+                static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
+                static_cast<uint64_t>(
+                        static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                        static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                        static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
+        mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+        }
+    }
+
+    ::android::sp<::android::GraphicBuffer> allocate() {
+        return ::android::sp<::android::GraphicBuffer>::make(
+                mDisplayWidth, mDisplayHeight, ::android::PIXEL_FORMAT_RGBA_8888,
+                /*layerCount*/ 1,
+                static_cast<uint64_t>(static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                                      static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
+                "VtsHalGraphicsComposer3_ReadbackTest");
+    }
+
+    void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+        for (auto layer : layers) {
+            layer->write(mWriter);
+        }
+        execute();
+    }
+
+    void execute() {
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
+        }
+
+        std::vector<command::CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
+
+        mReader.parse(results);
+        mWriter.reset();
+    }
+
+    bool getHasReadbackBuffer() {
+        ReadbackBufferAttributes readBackBufferAttributes;
+        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+                                                                        &readBackBufferAttributes);
+        mPixelFormat = readBackBufferAttributes.format;
+        mDataspace = readBackBufferAttributes.dataspace;
+        return error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
+    }
+
+    std::shared_ptr<IComposer> mComposer;
+    std::shared_ptr<IComposerClient> mComposerClient;
+
+    std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+    // the first display and is assumed never to be removed
+    int64_t mPrimaryDisplay;
+    int64_t mInvalidDisplayId;
+    int32_t mDisplayWidth;
+    int32_t mDisplayHeight;
+    std::vector<ColorMode> mTestColorModes;
+    CommandWriterBase mWriter;
+    CommandReaderBase mReader;
+    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+    std::unique_ptr<TestRenderEngine> mTestRenderEngine;
+
+    common::PixelFormat mPixelFormat;
+    common::Dataspace mDataspace;
+
+    static constexpr uint32_t kClientTargetSlotCount = 64;
+
+  private:
+    int64_t waitForFirstDisplay() {
+        while (true) {
+            std::vector<int64_t> displays = mComposerCallback->getDisplays();
+            if (displays.empty()) {
+                usleep(5 * 1000);
+                continue;
+            }
+            return displays[0];
+        }
+    }
+
+    void setTestColorModes() {
+        mTestColorModes.clear();
+        std::vector<ColorMode> modes;
+        EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+
+        for (ColorMode mode : modes) {
+            if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
+                          mode) != ReadbackHelper::colorModes.end()) {
+                mTestColorModes.push_back(mode);
+            }
+        }
+    }
+
+    // returns an invalid display id (one that has not been registered to a
+    // display.  Currently assuming that a device will never have close to
+    // std::numeric_limit<uint64_t>::max() displays registered while running tests
+    int64_t GetInvalidDisplayId() {
+        int64_t id = std::numeric_limits<int64_t>::max();
+        std::vector<int64_t> displays = mComposerCallback->getDisplays();
+        while (id > 0) {
+            if (std::none_of(displays.begin(), displays.end(),
+                             [&](const auto& display) { return id == display; })) {
+                return id;
+            }
+            id--;
+        }
+
+        // Although 0 could be an invalid display, a return value of 0
+        // from GetInvalidDisplayId means all other ids are in use, a condition which
+        // we are assuming a device will never have
+        EXPECT_NE(0, id);
+        return id;
+    }
+};
+
+class GraphicsCompositionTest : public GraphicsCompositionTestBase,
+                                public testing::WithParamInterface<std::string> {
+  public:
+    void SetUp() override { SetUpBase(GetParam()); }
+};
+
+TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        common::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setColor(BLUE);
+        layer->setDisplayFrame(coloredSquare);
+        layer->setZOrder(10);
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        // expected color for each pixel
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        // if hwc cannot handle and asks for composition change,
+        // just succeed the test
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(layers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+                                       GREEN);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+                                       BLUE);
+
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, common::PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(layers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        common::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setColor(BLUE);
+        layer->setDisplayFrame(coloredSquare);
+        layer->setZOrder(10);
+        layer->write(mWriter);
+
+        // This following buffer call should have no effect
+        uint64_t usage =
+                static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                                      static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN));
+
+        mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
+                                   static_cast<uint32_t>(mDisplayHeight), 1,
+                                   static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer->getLayer(), 0, mGraphicBuffer->handle, -1);
+
+        // expected color for each pixel
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadDisplay) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ASSERT_NE(nullptr, mGraphicBuffer);
+    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+    aidl::android::hardware::common::NativeHandle bufferHandle =
+            ::android::dupToAidl(mGraphicBuffer->handle);
+    ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+
+    const auto error = mComposerClient->setReadbackBuffer(mInvalidDisplayId, bufferHandle, fence);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadParameter) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    aidl::android::hardware::common::NativeHandle bufferHandle = ::android::dupToAidl(nullptr);
+    ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
+    const auto error =
+            mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ndk::ScopedFileDescriptor releaseFence;
+    const auto error = mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &releaseFence);
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, ClientComposition) {
+    EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)
+                        .isOk());
+
+    for (ColorMode mode : mTestColorModes) {
+        EXPECT_TRUE(mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+                                       GREEN);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+                                       BLUE);
+
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_FP16);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            ASSERT_EQ(1, changedCompositionLayers.size());
+            ASSERT_EQ(1, changedCompositionTypes.size());
+            ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
+
+            PixelFormat clientFormat = PixelFormat::RGBA_8888;
+            auto clientUsage = static_cast<uint32_t>(
+                    static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                    static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                    static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+            Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
+            common::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+
+            // create client target buffer
+            mGraphicBuffer->reallocate(layer->getWidth(), layer->getHeight(),
+                                       static_cast<int32_t>(common::PixelFormat::RGBA_8888),
+                                       layer->getLayerCount(), clientUsage);
+
+            ASSERT_NE(nullptr, mGraphicBuffer->handle);
+
+            void* clientBufData;
+            mGraphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
+
+            ASSERT_NO_FATAL_FAILURE(
+                    ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(),
+                                               static_cast<uint32_t>(mGraphicBuffer->stride),
+                                               clientBufData, clientFormat, expectedColors));
+            EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+
+            ndk::ScopedFileDescriptor fenceHandle;
+            EXPECT_TRUE(
+                    mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
+
+            layer->setToClientComposition(mWriter);
+            mWriter.acceptDisplayChanges(mPrimaryDisplay);
+            mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                    clientDataspace, std::vector<common::Rect>(1, damage));
+            execute();
+            mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                                &changedCompositionTypes);
+            ASSERT_TRUE(changedCompositionLayers.empty());
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
+    ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        auto deviceLayer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight / 2, PixelFormat::RGBA_8888);
+        std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
+        ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
+                                       {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
+                                        static_cast<int32_t>(deviceLayer->getHeight())},
+                                       GREEN);
+        deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
+                                      static_cast<int32_t>(deviceLayer->getHeight())});
+        deviceLayer->setZOrder(10);
+        deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+        deviceLayer->write(mWriter);
+
+        PixelFormat clientFormat = PixelFormat::RGBA_8888;
+        auto clientUsage = static_cast<uint32_t>(
+                static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+        Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
+        int32_t clientWidth = mDisplayWidth;
+        int32_t clientHeight = mDisplayHeight / 2;
+
+        auto clientLayer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, clientWidth,
+                clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+        common::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+        clientLayer->setDisplayFrame(clientFrame);
+        clientLayer->setZOrder(0);
+        clientLayer->write(mWriter);
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (changedCompositionTypes.size() != 1) {
+            continue;
+        }
+        // create client target buffer
+        ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
+        mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
+                                   static_cast<uint32_t>(mDisplayHeight),
+                                   static_cast<int32_t>(common::PixelFormat::RGBA_8888),
+                                   clientLayer->getLayerCount(), clientUsage);
+        ASSERT_NE(nullptr, mGraphicBuffer->handle);
+
+        void* clientBufData;
+        mGraphicBuffer->lock(clientUsage, {0, 0, mDisplayWidth, mDisplayHeight}, &clientBufData);
+
+        std::vector<Color> clientColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(clientColors, mDisplayWidth, clientFrame, RED);
+        ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
+                static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight),
+                mGraphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
+        EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+
+        ndk::ScopedFileDescriptor fenceHandle;
+        EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
+
+        clientLayer->setToClientComposition(mWriter);
+        mWriter.acceptDisplayChanges(mPrimaryDisplay);
+        mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                clientDataspace, std::vector<common::Rect>(1, clientFrame));
+        execute();
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_EQ(0, changedCompositionLayers.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerDamage) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        common::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+        // update surface damage and recheck
+        redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
+        ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+        ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
+        layer->setSurfaceDamage(
+                std::vector<common::Rect>(1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        layer->setColor(RED);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setAlpha(0);
+        layer->setBlendMode(BlendMode::PREMULTIPLIED);
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(layers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+                                       BLUE);
+
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
+                              static_cast<float>(mDisplayWidth),
+                              static_cast<float>(mDisplayHeight)});
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+        // update expected colors to match crop
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(layers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        common::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
+        common::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
+        auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        redLayer->setColor(RED);
+        redLayer->setDisplayFrame(redRect);
+
+        auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        blueLayer->setColor(BLUE);
+        blueLayer->setDisplayFrame(blueRect);
+        blueLayer->setZOrder(5);
+
+        std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+        // red in front of blue
+        redLayer->setZOrder(10);
+
+        // fill blue first so that red will overwrite on overlap
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+        redLayer->setZOrder(1);
+        ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        writeLayers(layers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(layers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+class GraphicsBlendModeCompositionTest
+    : public GraphicsCompositionTestBase,
+      public testing::WithParamInterface<std::tuple<std::string, std::string>> {
+  public:
+    void SetUp() override {
+        SetUpBase(std::get<0>(GetParam()));
+        mBackgroundColor = BLACK;
+        mTopLayerColor = RED;
+    }
+
+    void setBackgroundColor(Color color) { mBackgroundColor = color; }
+
+    void setTopLayerColor(Color color) { mTopLayerColor = color; }
+
+    void setUpLayers(BlendMode blendMode) {
+        mLayers.clear();
+        std::vector<Color> topLayerPixelColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(topLayerPixelColors, mDisplayWidth,
+                                       {0, 0, mDisplayWidth, mDisplayHeight}, mTopLayerColor);
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+        backgroundLayer->setColor(mBackgroundColor);
+
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        layer->setDataspace(Dataspace::UNKNOWN, mWriter);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
+
+        layer->setBlendMode(blendMode);
+        layer->setAlpha(std::stof(std::get<1>(GetParam())));
+
+        mLayers.push_back(backgroundLayer);
+        mLayers.push_back(layer);
+    }
+
+    void setExpectedColors(std::vector<Color>& expectedColors) {
+        ASSERT_EQ(2, mLayers.size());
+        ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+
+        auto layer = mLayers[1];
+        BlendMode blendMode = layer->getBlendMode();
+        float alpha = mTopLayerColor.a / 255.0f * layer->getAlpha();
+        if (blendMode == BlendMode::NONE) {
+            for (auto& expectedColor : expectedColors) {
+                expectedColor.r = mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha());
+                expectedColor.g = mTopLayerColor.g * static_cast<int8_t>(layer->getAlpha());
+                expectedColor.b = mTopLayerColor.b * static_cast<int8_t>(layer->getAlpha());
+                expectedColor.a = static_cast<int8_t>(alpha * 255.0);
+            }
+        } else if (blendMode == BlendMode::PREMULTIPLIED) {
+            for (auto& expectedColor : expectedColors) {
+                expectedColor.r = static_cast<int8_t>(
+                        mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha()) +
+                        mBackgroundColor.r * (1.0 - alpha));
+                expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * layer->getAlpha() +
+                                                      mBackgroundColor.g * (1.0 - alpha));
+                expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * layer->getAlpha() +
+                                                      mBackgroundColor.b * (1.0 - alpha));
+                expectedColor.a = static_cast<int8_t>(alpha + mBackgroundColor.a * (1.0 - alpha));
+            }
+        } else if (blendMode == BlendMode::COVERAGE) {
+            for (auto& expectedColor : expectedColors) {
+                expectedColor.r = static_cast<int8_t>(mTopLayerColor.r * alpha +
+                                                      mBackgroundColor.r * (1.0 - alpha));
+                expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * alpha +
+                                                      mBackgroundColor.g * (1.0 - alpha));
+                expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * alpha +
+                                                      mBackgroundColor.b * (1.0 - alpha));
+                expectedColor.a = static_cast<int8_t>(mTopLayerColor.a * alpha +
+                                                      mBackgroundColor.a * (1.0 - alpha));
+            }
+        }
+    }
+
+  protected:
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    Color mBackgroundColor;
+    Color mTopLayerColor;
+};
+
+TEST_P(GraphicsBlendModeCompositionTest, None) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+        setBackgroundColor(BLACK);
+        setTopLayerColor(TRANSLUCENT_RED);
+        setUpLayers(BlendMode::NONE);
+        setExpectedColors(expectedColors);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(mLayers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+        setBackgroundColor(BLACK);
+        setTopLayerColor(TRANSLUCENT_RED);
+
+        setUpLayers(BlendMode::COVERAGE);
+        setExpectedColors(expectedColors);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+        setBackgroundColor(BLACK);
+        setTopLayerColor(TRANSLUCENT_RED);
+        setUpLayers(BlendMode::PREMULTIPLIED);
+        setExpectedColors(expectedColors);
+
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(mLayers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
+  protected:
+    void SetUp() override {
+        GraphicsCompositionTest::SetUp();
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setColor({0, 0, 0, 0});
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+
+        mSideLength = mDisplayWidth < mDisplayHeight ? mDisplayWidth : mDisplayHeight;
+        common::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
+        common::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength};
+
+        mLayer = std::make_shared<TestBufferLayer>(mComposerClient, mGraphicBuffer,
+                                                   *mTestRenderEngine, mPrimaryDisplay, mSideLength,
+                                                   mSideLength, PixelFormat::RGBA_8888);
+        mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
+        mLayer->setZOrder(10);
+
+        std::vector<Color> baseColors(static_cast<size_t>(mSideLength * mSideLength));
+        ReadbackHelper::fillColorsArea(baseColors, mSideLength, redRect, RED);
+        ReadbackHelper::fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
+        ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
+        mLayers = {backgroundLayer, mLayer};
+    }
+
+  protected:
+    std::shared_ptr<TestBufferLayer> mLayer;
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    int mSideLength;
+};
+
+TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
+    for (ColorMode mode : mTestColorModes) {
+        auto error =
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC);
+        if (!error.isOk() &&
+            (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
+             error.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
+            SUCCEED() << "ColorMode not supported, skip test";
+            return;
+        }
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+        mLayer->setTransform(Transform::FLIP_H);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
+
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(mLayers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        mLayer->setTransform(Transform::FLIP_V);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
+
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(mLayers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+TEST_P(GraphicsTransformCompositionTest, ROT_180) {
+    for (ColorMode mode : mTestColorModes) {
+        ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+        if (!getHasReadbackBuffer()) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+                                      mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+        mLayer->setTransform(Transform::ROT_180);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+        std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength},
+                                       RED);
+        ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+                                       {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
+
+        writeLayers(mLayers);
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+        mTestRenderEngine->setRenderLayers(mLayers);
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+        ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsCompositionTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest);
+INSTANTIATE_TEST_SUITE_P(BlendMode, GraphicsBlendModeCompositionTest,
+                         testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
+                                                  IComposer::descriptor)),
+                                          testing::Values("0.2", "1.0")));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsTransformCompositionTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index 3fbb105..7a20a53 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1,22 +1,36 @@
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/command-buffer.h>
 #include <binder/ProcessState.h>
-#include <composer-vts/include/GraphicsComposerCallback.h>
 #include <gtest/gtest.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
 #include <algorithm>
+#include <numeric>
 #include <regex>
 #include <string>
 #include <thread>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
+#include "composer-vts/include/GraphicsComposerCallback.h"
 
-#pragma push_macro("LOG_TAG")
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 #undef LOG_TAG
 #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
 
@@ -25,6 +39,9 @@
 
 using namespace std::chrono_literals;
 
+using ::android::GraphicBuffer;
+using ::android::sp;
+
 class VtsDisplay {
   public:
     VtsDisplay(int64_t displayId, int32_t displayWidth, int32_t displayHeight)
@@ -32,6 +49,12 @@
 
     int64_t get() const { return mDisplayId; }
 
+    FRect getCrop() const {
+        return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
+    }
+
+    Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+
     void setDimensions(int32_t displayWidth, int32_t displayHeight) {
         mDisplayWidth = displayWidth;
         mDisplayHeight = displayHeight;
@@ -52,13 +75,115 @@
         ASSERT_NO_FATAL_FAILURE(mComposer = IComposer::fromBinder(binder));
         ASSERT_NE(mComposer, nullptr);
         ASSERT_NO_FATAL_FAILURE(mComposer->createClient(&mComposerClient));
-        mInvalidDisplayId = GetInvalidDisplayId();
 
         mComposerCallback = ::ndk::SharedRefBase::make<GraphicsComposerCallback>();
         EXPECT_TRUE(mComposerClient->registerCallback(mComposerCallback).isOk());
 
         // assume the first displays are built-in and are never removed
         mDisplays = waitForDisplays();
+        mPrimaryDisplay = mDisplays[0].get();
+        ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
+        int32_t activeConfig;
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                  DisplayAttribute::WIDTH, &mDisplayWidth)
+                            .isOk());
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                  DisplayAttribute::HEIGHT, &mDisplayHeight)
+                            .isOk());
+
+        // explicitly disable vsync
+        for (const auto& display : mDisplays) {
+            EXPECT_TRUE(mComposerClient->setVsyncEnabled(display.get(), false).isOk());
+        }
+        mComposerCallback->setVsyncAllowed(false);
+    }
+
+    void TearDown() override {
+        destroyAllLayers();
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncPeriodChangeCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidSeamlessPossibleCount());
+        }
+    }
+
+    void Test_setContentTypeForDisplay(const int64_t& display,
+                                       const std::vector<ContentType>& capabilities,
+                                       const ContentType& contentType, const char* contentTypeStr) {
+        const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
+                                                  contentType) != capabilities.end();
+
+        if (!contentTypeSupport) {
+            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
+                      mComposerClient->setContentType(display, contentType)
+                              .getServiceSpecificError());
+            GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
+                            << std::to_string(display) << ", skipping test";
+            return;
+        }
+
+        EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
+        EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
+    }
+
+    void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
+        for (const auto& display : mDisplays) {
+            std::vector<ContentType> supportedContentTypes;
+            const auto error = mComposerClient->getSupportedContentTypes(display.get(),
+                                                                         &supportedContentTypes);
+            EXPECT_TRUE(error.isOk());
+
+            Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
+                                          contentTypeStr);
+        }
+    }
+
+    int64_t createLayer(const VtsDisplay& display) {
+        int64_t layer;
+        EXPECT_TRUE(mComposerClient->createLayer(display.get(), kBufferSlotCount, &layer).isOk());
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        if (resourceIt == mDisplayResources.end()) {
+            resourceIt = mDisplayResources.insert({display.get(), DisplayResource(false)}).first;
+        }
+
+        EXPECT_TRUE(resourceIt->second.layers.insert(layer).second)
+                << "duplicated layer id " << layer;
+
+        return layer;
+    }
+
+    void destroyAllLayers() {
+        for (const auto& it : mDisplayResources) {
+            auto display = it.first;
+            const DisplayResource& resource = it.second;
+
+            for (auto layer : resource.layers) {
+                const auto error = mComposerClient->destroyLayer(display, layer);
+                EXPECT_TRUE(error.isOk());
+            }
+
+            if (resource.isVirtual) {
+                const auto error = mComposerClient->destroyVirtualDisplay(display);
+                EXPECT_TRUE(error.isOk());
+            }
+        }
+        mDisplayResources.clear();
+    }
+
+    void destroyLayer(const VtsDisplay& display, int64_t layer) {
+        auto const error = mComposerClient->destroyLayer(display.get(), layer);
+        ASSERT_TRUE(error.isOk()) << "failed to destroy layer " << layer;
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        ASSERT_NE(mDisplayResources.end(), resourceIt);
+        resourceIt->second.layers.erase(layer);
     }
 
     // returns an invalid display id (one that has not been registered to a
@@ -74,7 +199,11 @@
             id--;
         }
 
-        return 0;
+        // Although 0 could be an invalid display, a return value of 0
+        // from GetInvalidDisplayId means all other ids are in use, a condition which
+        // we are assuming a device will never have
+        EXPECT_NE(0, id);
+        return id;
     }
 
     std::vector<VtsDisplay> waitForDisplays() {
@@ -133,42 +262,31 @@
         return error;
     }
 
-    void Test_setContentTypeForDisplay(const int64_t& display,
-                                       const std::vector<ContentType>& capabilities,
-                                       const ContentType& contentType, const char* contentTypeStr) {
-        const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
-                                                  contentType) != capabilities.end();
+    struct TestParameters {
+        nsecs_t delayForChange;
+        bool refreshMiss;
+    };
 
-        if (!contentTypeSupport) {
-            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
-                      mComposerClient->setContentType(display, contentType)
-                              .getServiceSpecificError());
-            GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
-                            << std::to_string(display) << ", skipping test";
-            return;
-        }
+    // Keep track of all virtual displays and layers.  When a test fails with
+    // ASSERT_*, the destructor will clean up the resources for the test.
+    struct DisplayResource {
+        DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
 
-        EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
-        EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
-    }
-
-    void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
-        for (const auto& display : mDisplays) {
-            std::vector<ContentType> supportedContentTypes;
-            const auto error = mComposerClient->getSupportedContentTypes(display.get(),
-                                                                         &supportedContentTypes);
-            EXPECT_TRUE(error.isOk());
-
-            Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
-                                          contentTypeStr);
-        }
-    }
+        bool isVirtual;
+        std::unordered_set<int64_t> layers;
+    };
 
     std::shared_ptr<IComposer> mComposer;
     std::shared_ptr<IComposerClient> mComposerClient;
     int64_t mInvalidDisplayId;
+    int64_t mPrimaryDisplay;
     std::vector<VtsDisplay> mDisplays;
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+    // use the slot count usually set by SF
+    static constexpr uint32_t kBufferSlotCount = 64;
+    std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+    int32_t mDisplayWidth;
+    int32_t mDisplayHeight;
 };
 
 TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBadDisplay) {
@@ -187,6 +305,317 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, DumpDebugInfo) {
+    std::string debugInfo;
+    EXPECT_TRUE(mComposer->dumpDebugInfo(&debugInfo).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateClientSingleton) {
+    std::shared_ptr<IComposerClient> composerClient;
+    const auto error = mComposer->createClient(&composerClient);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_NO_RESOURCES, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
+    DisplayIdentification displayIdentification0;
+
+    const auto error =
+            mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification0);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        return;
+    }
+    ASSERT_TRUE(error.isOk()) << "failed to get display identification data";
+    ASSERT_FALSE(displayIdentification0.data.empty());
+
+    constexpr size_t kEdidBlockSize = 128;
+    ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
+            << "EDID blob length is not a multiple of " << kEdidBlockSize;
+
+    const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+    ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
+                           displayIdentification0.data.begin()))
+            << "EDID blob doesn't start with the fixed EDID header";
+    ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
+                                 displayIdentification0.data.begin() + kEdidBlockSize,
+                                 static_cast<uint8_t>(0)))
+            << "EDID base block doesn't checksum";
+
+    DisplayIdentification displayIdentification1;
+    ASSERT_TRUE(
+            mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification1)
+                    .isOk());
+
+    ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
+    ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
+                std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
+                           displayIdentification1.data.begin()))
+            << "data is not stable";
+}
+
+TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
+    HdrCapabilities hdrCapabilities;
+    const auto error = mComposerClient->getHdrCapabilities(mPrimaryDisplay, &hdrCapabilities);
+
+    ASSERT_TRUE(error.isOk());
+    ASSERT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
+    std::vector<PerFrameMetadataKey> keys;
+    const auto error = mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay, &keys);
+
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
+        return;
+    }
+    EXPECT_TRUE(error.isOk());
+    ASSERT_TRUE(keys.size() >= 0);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
+    ReadbackBufferAttributes readBackBufferAttributes;
+    const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+                                                                    &readBackBufferAttributes);
+
+    if (error.isOk()) {
+        EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
+    std::vector<ColorMode> modes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+    for (auto mode : modes) {
+        std::vector<RenderIntent> intents;
+        EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk());
+
+        bool isHdr;
+        switch (mode) {
+            case ColorMode::BT2100_PQ:
+            case ColorMode::BT2100_HLG:
+                isHdr = true;
+                break;
+            default:
+                isHdr = false;
+                break;
+        }
+        RenderIntent requiredIntent =
+                isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
+
+        auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
+        EXPECT_NE(intents.cend(), iter);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadDisplay) {
+    std::vector<ColorMode> modes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+    for (auto mode : modes) {
+        std::vector<RenderIntent> renderIntents;
+        const auto error =
+                mComposerClient->getRenderIntents(mInvalidDisplayId, mode, &renderIntents);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadParameter) {
+    std::vector<RenderIntent> renderIntents;
+    const auto error = mComposerClient->getRenderIntents(
+            mPrimaryDisplay, static_cast<ColorMode>(-1), &renderIntents);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModes) {
+    std::vector<ColorMode> colorModes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+
+    auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
+    ASSERT_NE(colorModes.cend(), native);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModeBadDisplay) {
+    std::vector<ColorMode> colorModes;
+    const auto error = mComposerClient->getColorModes(mInvalidDisplayId, &colorModes);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorMode) {
+    std::vector<ColorMode> colorModes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+    for (auto mode : colorModes) {
+        std::vector<RenderIntent> intents;
+        EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk())
+                << "failed to get render intents";
+        for (auto intent : intents) {
+            const auto error = mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
+            EXPECT_TRUE(error.isOk() ||
+                        IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+                    << "failed to set color mode";
+        }
+    }
+
+    const auto error = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+                                                     RenderIntent::COLORIMETRIC);
+    EXPECT_TRUE(error.isOk() || IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+            << "failed to set color mode";
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadDisplay) {
+    std::vector<ColorMode> colorModes;
+    EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+    for (auto mode : colorModes) {
+        std::vector<RenderIntent> intents;
+        EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk())
+                << "failed to get render intents";
+        for (auto intent : intents) {
+            auto const error = mComposerClient->setColorMode(mInvalidDisplayId, mode, intent);
+
+            EXPECT_FALSE(error.isOk());
+            ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadParameter) {
+    const auto colorModeError = mComposerClient->setColorMode(
+            mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
+
+    EXPECT_FALSE(colorModeError.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, colorModeError.getServiceSpecificError());
+
+    const auto renderIntentError = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+                                                                 static_cast<RenderIntent>(-1));
+
+    EXPECT_FALSE(renderIntentError.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, renderIntentError.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
+    int constexpr invalid = -1;
+
+    DisplayContentSamplingAttributes format;
+    auto error = mComposerClient->getDisplayedContentSamplingAttributes(mPrimaryDisplay, &format);
+
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_NE(format.format, static_cast<common::PixelFormat>(invalid));
+    EXPECT_NE(format.dataspace, static_cast<common::Dataspace>(invalid));
+    EXPECT_NE(format.componentMask, static_cast<FormatColorComponent>(invalid));
+};
+
+TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
+    auto const maxFrames = 10;
+    FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
+    auto error = mComposerClient->setDisplayedContentSamplingEnabled(
+            mPrimaryDisplay, true, enableAllComponents, maxFrames);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+    EXPECT_TRUE(error.isOk());
+
+    error = mComposerClient->setDisplayedContentSamplingEnabled(mPrimaryDisplay, false,
+                                                                enableAllComponents, maxFrames);
+    EXPECT_TRUE(error.isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
+    DisplayContentSamplingAttributes displayContentSamplingAttributes;
+    int constexpr invalid = -1;
+    displayContentSamplingAttributes.format = static_cast<common::PixelFormat>(invalid);
+    displayContentSamplingAttributes.dataspace = static_cast<common::Dataspace>(invalid);
+    displayContentSamplingAttributes.componentMask = static_cast<FormatColorComponent>(invalid);
+    auto error = mComposerClient->getDisplayedContentSamplingAttributes(
+            mPrimaryDisplay, &displayContentSamplingAttributes);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Sampling attributes aren't supported on this device, test skipped";
+        return;
+    }
+
+    int64_t maxFrames = 10;
+    int64_t timestamp = 0;
+    int64_t frameCount = 0;
+    DisplayContentSample displayContentSample;
+    error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
+                                                       &displayContentSample);
+    if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_LE(frameCount, maxFrames);
+    std::vector<std::vector<int64_t>> histogram = {
+            displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
+            displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
+
+    for (size_t i = 0; i < histogram.size(); i++) {
+        const bool shouldHaveHistogram =
+                static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
+        EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBasic) {
+    std::vector<DisplayCapability> capabilities;
+    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    const bool hasDozeSupport = std::find(capabilities.begin(), capabilities.end(),
+                                          DisplayCapability::DOZE) != capabilities.end();
+    bool isDozeSupported = false;
+    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    EXPECT_EQ(hasDozeSupport, isDozeSupported);
+
+    bool hasBrightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+                                          DisplayCapability::BRIGHTNESS) != capabilities.end();
+    bool isBrightnessSupported = false;
+    EXPECT_TRUE(
+            mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay, &isBrightnessSupported)
+                    .isOk());
+    EXPECT_EQ(isBrightnessSupported, hasBrightnessSupport);
+}
+
+/*
+ * Test that if brightness operations are supported, setDisplayBrightness works as expected.
+ */
+TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) {
+    std::vector<DisplayCapability> capabilities;
+    auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+                                       DisplayCapability::BRIGHTNESS) != capabilities.end();
+    if (!brightnessSupport) {
+        EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f)
+                          .getServiceSpecificError(),
+                  IComposerClient::EX_UNSUPPORTED);
+        GTEST_SUCCEED() << "Brightness operations are not supported";
+        return;
+    }
+
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk());
+    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk());
+
+    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+
+    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f);
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+}
+
 TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) {
     DisplayConnectionType type;
     EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk());
@@ -198,7 +627,7 @@
 TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) {
     for (const auto& display : mDisplays) {
         std::vector<int32_t> configs;
-        mComposerClient->getDisplayConfigs(display.get(), &configs);
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
         for (const auto& config : configs) {
             const std::array<DisplayAttribute, 4> requiredAttributes = {{
                     DisplayAttribute::WIDTH,
@@ -234,7 +663,7 @@
 TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) {
     for (const auto& display : mDisplays) {
         std::vector<int32_t> configs;
-        mComposerClient->getDisplayConfigs(display.get(), &configs);
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
 
         EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
             return config == IComposerClient::INVALID_CONFIGURATION;
@@ -436,7 +865,7 @@
     std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
     std::unordered_set<std::string> uniqueNames;
     for (const auto& key : keys) {
-        std::string name(key.name.c_str());
+        std::string name(key.name);
 
         // Keys must not start with 'android' or 'com.android'
         EXPECT_FALSE(name.find("android") == 0);
@@ -451,6 +880,1060 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
+    int32_t maxVirtualDisplayCount;
+    EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&maxVirtualDisplayCount).isOk());
+    if (maxVirtualDisplayCount == 0) {
+        GTEST_SUCCEED() << "no virtual display support";
+        return;
+    }
+
+    VirtualDisplay virtualDisplay;
+
+    EXPECT_TRUE(mComposerClient
+                        ->createVirtualDisplay(64, 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
+                                               kBufferSlotCount, &virtualDisplay)
+                        .isOk());
+
+    ASSERT_TRUE(mDisplayResources.insert({virtualDisplay.display, DisplayResource(true)}).second)
+            << "duplicated virtual display id " << virtualDisplay.display;
+
+    EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, DestroyVirtualDisplayBadDisplay) {
+    int32_t maxDisplayCount = 0;
+    EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&maxDisplayCount).isOk());
+    if (maxDisplayCount == 0) {
+        GTEST_SUCCEED() << "no virtual display support";
+        return;
+    }
+    const auto error = mComposerClient->destroyVirtualDisplay(mInvalidDisplayId);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateLayer) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateLayerBadDisplay) {
+    int64_t layer;
+    const auto error = mComposerClient->createLayer(mInvalidDisplayId, kBufferSlotCount, &layer);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, DestroyLayerBadDisplay) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    const auto error = mComposerClient->destroyLayer(mInvalidDisplayId, layer);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+    EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, DestroyLayerBadLayerError) {
+    // We haven't created any layers yet, so any id should be invalid
+    const auto error = mComposerClient->destroyLayer(mPrimaryDisplay, 1);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_LAYER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetActiveConfigBadDisplay) {
+    int32_t config;
+    const auto error = mComposerClient->getActiveConfig(mInvalidDisplayId, &config);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfig) {
+    std::vector<int32_t> configs;
+    EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfigBadDisplay) {
+    std::vector<int32_t> configs;
+    const auto error = mComposerClient->getDisplayConfigs(mInvalidDisplayId, &configs);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayName) {
+    std::string displayName;
+    EXPECT_TRUE(mComposerClient->getDisplayName(mPrimaryDisplay, &displayName).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) {
+    EXPECT_TRUE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetActiveConfig) {
+    std::vector<int32_t> configs;
+    EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+    for (auto config : configs) {
+        EXPECT_TRUE(mComposerClient->setActiveConfig(mPrimaryDisplay, config).isOk());
+        int32_t config1;
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+        EXPECT_EQ(config, config1);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetActiveConfigPowerCycle) {
+    EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
+    EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
+
+    std::vector<int32_t> configs;
+    EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+    for (auto config : configs) {
+        EXPECT_TRUE(mComposerClient->setActiveConfig(mPrimaryDisplay, config).isOk());
+        int32_t config1;
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+        EXPECT_EQ(config, config1);
+
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+        EXPECT_EQ(config, config1);
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDozeSupportBadDisplay) {
+    bool isDozeSupport;
+    const auto error = mComposerClient->getDozeSupport(mInvalidDisplayId, &isDozeSupport);
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
+    bool isDozeSupported;
+    mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk();
+    if (!isDozeSupported) {
+        auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+
+        error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE_SUSPEND);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
+    mComposerCallback->setVsyncAllowed(true);
+
+    EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, true).isOk());
+    usleep(60 * 1000);
+    EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
+
+    mComposerCallback->setVsyncAllowed(false);
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
+    std::vector<PowerMode> modes;
+    modes.push_back(PowerMode::OFF);
+    modes.push_back(PowerMode::ON_SUSPEND);
+    modes.push_back(PowerMode::ON);
+
+    bool isDozeSupported;
+    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    if (isDozeSupported) {
+        modes.push_back(PowerMode::DOZE);
+        modes.push_back(PowerMode::DOZE_SUSPEND);
+    }
+
+    for (auto mode : modes) {
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
+    std::vector<PowerMode> modes;
+
+    modes.push_back(PowerMode::OFF);
+    modes.push_back(PowerMode::ON);
+    modes.push_back(PowerMode::OFF);
+    for (auto mode : modes) {
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    }
+    modes.clear();
+
+    modes.push_back(PowerMode::OFF);
+    modes.push_back(PowerMode::OFF);
+    for (auto mode : modes) {
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    }
+    modes.clear();
+
+    modes.push_back(PowerMode::ON);
+    modes.push_back(PowerMode::ON);
+    for (auto mode : modes) {
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    }
+    modes.clear();
+
+    modes.push_back(PowerMode::ON_SUSPEND);
+    modes.push_back(PowerMode::ON_SUSPEND);
+    for (auto mode : modes) {
+        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    }
+    modes.clear();
+
+    bool isDozeSupported = false;
+    ASSERT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    if (isDozeSupported) {
+        modes.push_back(PowerMode::DOZE);
+        modes.push_back(PowerMode::DOZE);
+        for (auto mode : modes) {
+            EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+        }
+        modes.clear();
+
+        modes.push_back(PowerMode::DOZE_SUSPEND);
+        modes.push_back(PowerMode::DOZE_SUSPEND);
+        for (auto mode : modes) {
+            EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeBadDisplay) {
+    const auto error = mComposerClient->setPowerMode(mInvalidDisplayId, PowerMode::ON);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeBadParameter) {
+    const auto error = mComposerClient->setPowerMode(mPrimaryDisplay, static_cast<PowerMode>(-1));
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
+    std::vector<float> matrix;
+    EXPECT_TRUE(
+            mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR, &matrix)
+                    .isOk());
+
+    // the last row is known
+    ASSERT_EQ(0.0f, matrix[12]);
+    ASSERT_EQ(0.0f, matrix[13]);
+    ASSERT_EQ(0.0f, matrix[14]);
+    ASSERT_EQ(1.0f, matrix[15]);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrixBadParameter) {
+    std::vector<float> matrix;
+    const auto error =
+            mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::UNKNOWN, &matrix);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+// Tests for Command.
+class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
+  protected:
+    void TearDown() override {
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
+
+        ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
+    }
+
+    void execute() {
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
+        }
+
+        std::vector<command::CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
+
+        mReader.parse(results);
+        mWriter.reset();
+    }
+
+    static inline auto toTimePoint(nsecs_t time) {
+        return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
+    }
+
+    void setActiveConfig(VtsDisplay& display, int32_t config) {
+        EXPECT_TRUE(mComposerClient->setActiveConfig(display.get(), config).isOk());
+        int32_t displayWidth;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH,
+                                                  &displayWidth)
+                            .isOk());
+        int32_t displayHeight;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT,
+                                                  &displayHeight)
+                            .isOk());
+        display.setDimensions(displayWidth, displayHeight);
+    }
+
+    void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
+        std::vector<int32_t> displayConfigs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display, &displayConfigs).isOk());
+        for (const int32_t config1 : displayConfigs) {
+            for (const int32_t config2 : displayConfigs) {
+                if (config1 != config2) {
+                    func(config1, config2);
+                }
+            }
+        }
+    }
+
+    void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
+                                  int64_t desiredTimeNanos, int64_t oldPeriodNanos,
+                                  int64_t newPeriodNanos) {
+        const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
+        while (std::chrono::steady_clock::now() <= kChangeDeadline) {
+            int32_t vsyncPeriodNanos;
+            EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos).isOk());
+            if (systemTime() <= desiredTimeNanos) {
+                EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
+            } else if (vsyncPeriodNanos == newPeriodNanos) {
+                break;
+            }
+            std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
+        }
+    }
+
+    sp<GraphicBuffer> allocate() {
+        return sp<GraphicBuffer>::make(
+                static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight),
+                ::android::PIXEL_FORMAT_RGBA_8888,
+                /*layerCount*/ 1,
+                (static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY)),
+                "VtsHalGraphicsComposer3_TargetTest");
+    }
+
+    void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
+        if (timeline != nullptr) {
+            // Refresh time should be before newVsyncAppliedTimeNanos
+            EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
+
+            std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
+        }
+
+        EXPECT_TRUE(mComposerClient->setPowerMode(display.get(), PowerMode::ON).isOk());
+        EXPECT_TRUE(
+                mComposerClient
+                        ->setColorMode(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC)
+                        .isOk());
+
+        int64_t layer = 0;
+        ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
+        {
+            auto buffer = allocate();
+            ASSERT_NE(nullptr, buffer);
+            ASSERT_EQ(::android::OK, buffer->initCheck());
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter.setLayerCompositionType(display.get(), layer, Composition::DEVICE);
+            mWriter.setLayerDisplayFrame(display.get(), layer, display.getFrameRect());
+            mWriter.setLayerPlaneAlpha(display.get(), layer, 1);
+            mWriter.setLayerSourceCrop(display.get(), layer, display.getCrop());
+            mWriter.setLayerTransform(display.get(), layer, static_cast<Transform>(0));
+            mWriter.setLayerVisibleRegion(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerZOrder(display.get(), layer, 10);
+            mWriter.setLayerBlendMode(display.get(), layer, BlendMode::NONE);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerDataspace(display.get(), layer, common::Dataspace::UNKNOWN);
+
+            mWriter.validateDisplay(display.get());
+            execute();
+            ASSERT_TRUE(mReader.takeErrors().empty());
+
+            mWriter.presentDisplay(display.get());
+            execute();
+            ASSERT_TRUE(mReader.takeErrors().empty());
+        }
+
+        {
+            auto buffer = allocate();
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, {0, 0, 10, 10}));
+            mWriter.validateDisplay(display.get());
+            execute();
+            ASSERT_TRUE(mReader.takeErrors().empty());
+
+            mWriter.presentDisplay(display.get());
+            execute();
+        }
+
+        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
+    }
+
+    void Test_setActiveConfigWithConstraints(const TestParameters& params) {
+        for (VtsDisplay& display : mDisplays) {
+            forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+
+                int32_t vsyncPeriod1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod1)
+                                    .isOk());
+                int32_t configGroup1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup1)
+                                    .isOk());
+                int32_t vsyncPeriod2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod2)
+                                    .isOk());
+                int32_t configGroup2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup2)
+                                    .isOk());
+
+                if (vsyncPeriod1 == vsyncPeriod2) {
+                    return;  // continue
+                }
+
+                // We don't allow delayed change when changing config groups
+                if (params.delayForChange > 0 && configGroup1 != configGroup2) {
+                    return;  // continue
+                }
+
+                VsyncPeriodChangeTimeline timeline;
+                VsyncPeriodChangeConstraints constraints = {
+                        .desiredTimeNanos = systemTime() + params.delayForChange,
+                        .seamlessRequired = false};
+                EXPECT_TRUE(setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                    .isOk());
+
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+                // Refresh rate should change within a reasonable time
+                constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s;  // 1 second
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+                            kReasonableTimeForChange.count());
+
+                if (timeline.refreshRequired) {
+                    if (params.refreshMiss) {
+                        // Miss the refresh frame on purpose to make sure the implementation sends a
+                        // callback
+                        std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
+                                                      100ms);
+                    }
+                    sendRefreshFrame(display, &timeline);
+                }
+                waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
+                                         vsyncPeriod1, vsyncPeriod2);
+
+                // At this point the refresh rate should have changed already, however in rare
+                // cases the implementation might have missed the deadline. In this case a new
+                // timeline should have been provided.
+                auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+                if (timeline.refreshRequired && params.refreshMiss) {
+                    EXPECT_TRUE(newTimeline.has_value());
+                }
+
+                if (newTimeline.has_value()) {
+                    if (newTimeline->refreshRequired) {
+                        sendRefreshFrame(display, &newTimeline.value());
+                    }
+                    waitForVsyncPeriodChange(display.get(), newTimeline.value(),
+                                             constraints.desiredTimeNanos, vsyncPeriod1,
+                                             vsyncPeriod2);
+                }
+
+                int32_t vsyncPeriodNanos;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
+            });
+        }
+    }
+
+    // clang-format off
+    const std::array<float, 16> kIdentity = {{
+            1.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 1.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 1.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f,
+    }};
+    // clang-format on
+
+    CommandWriterBase mWriter;
+    CommandReaderBase mReader;
+};
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
+    mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data(), ColorTransform::IDENTITY);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+    mWriter.setLayerColorTransform(mPrimaryDisplay, layer, kIdentity.data());
+    execute();
+
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SUCCEED() << "setLayerColorTransform is not supported";
+        return;
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_CLIENT_TARGET) {
+    EXPECT_TRUE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
+
+    mWriter.setClientTarget(mPrimaryDisplay, 0, nullptr, -1, Dataspace::UNKNOWN,
+                            std::vector<Rect>());
+
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_OUTPUT_BUFFER) {
+    int32_t virtualDisplayCount;
+    EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&virtualDisplayCount).isOk());
+    if (virtualDisplayCount == 0) {
+        GTEST_SUCCEED() << "no virtual display support";
+        return;
+    }
+
+    VirtualDisplay display;
+    EXPECT_TRUE(mComposerClient
+                        ->createVirtualDisplay(64, 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
+                                               kBufferSlotCount, &display)
+                        .isOk());
+
+    auto handle = allocate()->handle;
+    mWriter.setOutputBuffer(display.display, 0, handle, -1);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
+    mWriter.validateDisplay(mPrimaryDisplay);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.acceptDisplayChanges(mPrimaryDisplay);
+    execute();
+}
+
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
+    execute();
+}
+
+/**
+ * Test IComposerClient::Command::PRESENT_DISPLAY
+ *
+ * Test that IComposerClient::Command::PRESENT_DISPLAY works without
+ * additional call to validateDisplay when only the layer buffer handle and
+ * surface damage have been set
+ */
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) {
+    std::vector<Capability> capabilities;
+    EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk());
+    if (none_of(capabilities.begin(), capabilities.end(),
+                [&](auto item) { return item == Capability::SKIP_VALIDATE; })) {
+        GTEST_SUCCEED() << "Device does not have skip validate capability, skipping";
+        return;
+    }
+    mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
+
+    std::vector<RenderIntent> renderIntents;
+    mComposerClient->getRenderIntents(mPrimaryDisplay, ColorMode::NATIVE, &renderIntents);
+    for (auto intent : renderIntents) {
+        mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE, intent);
+
+        auto handle = allocate()->handle;
+        ASSERT_NE(nullptr, handle);
+
+        Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+
+        int64_t layer;
+        EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+        mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+        mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+        mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+        mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                                   {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+        mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+        mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+        mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+        mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+
+        mWriter.validateDisplay(mPrimaryDisplay);
+        execute();
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
+            GTEST_SUCCEED() << "Composition change requested, skipping test";
+            return;
+        }
+
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        auto handle2 = allocate()->handle;
+        ASSERT_NE(nullptr, handle2);
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle2, -1);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, {0, 0, 10, 10}));
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+    }
+}
+
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_CURSOR_POSITION) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    auto handle = allocate()->handle;
+    ASSERT_NE(nullptr, handle);
+    Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                               {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+    mWriter.validateDisplay(mPrimaryDisplay);
+
+    execute();
+    std::vector<int64_t> layers;
+    std::vector<Composition> types;
+    mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+    if (!layers.empty()) {
+        GTEST_SUCCEED() << "Composition change requested, skipping test";
+        return;
+    }
+    mWriter.presentDisplay(mPrimaryDisplay);
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 1, 1);
+    execute();
+
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 0, 0);
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BUFFER) {
+    auto handle = allocate()->handle;
+    ASSERT_NE(nullptr, handle);
+
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    Rect empty{0, 0, 0, 0};
+    Rect unit{0, 0, 1, 1};
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::PREMULTIPLIED);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::COVERAGE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerColor(mPrimaryDisplay, layer,
+                          Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+                                static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0});
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CLIENT);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::SOLID_COLOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DATASPACE) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DISPLAY_FRAME) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, Rect{0, 0, 1, 1});
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PLANE_ALPHA) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 0.0f);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1.0f);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
+    std::vector<Capability> capabilities;
+    EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk());
+    if (none_of(capabilities.begin(), capabilities.end(),
+                [&](auto& item) { return item == Capability::SIDEBAND_STREAM; })) {
+        GTEST_SUCCEED() << "no sideband stream support";
+        return;
+    }
+
+    auto handle = allocate()->handle;
+    ASSERT_NE(nullptr, handle);
+
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerSidebandStream(mPrimaryDisplay, layer, handle);
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SOURCE_CROP) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
+    execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_TRANSFORM) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_H);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_V);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_90);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_180);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_270);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_VISIBLE_REGION) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    Rect empty{0, 0, 0, 0};
+    Rect unit{0, 0, 1, 1};
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_Z_ORDER) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 0);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    /**
+     * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
+     * the D65 white point and the SRGB transfer functions.
+     * Rendering Intent: Colorimetric
+     * Primaries:
+     *                  x       y
+     *  green           0.265   0.690
+     *  blue            0.150   0.060
+     *  red             0.680   0.320
+     *  white (D65)     0.3127  0.3290
+     */
+
+    std::vector<PerFrameMetadata> aidlMetadata;
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265f});
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690f});
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150f});
+    aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060f});
+    aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_X, 0.3127f});
+    aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_Y, 0.3290f});
+    aidlMetadata.push_back({PerFrameMetadataKey::MAX_LUMINANCE, 100.0f});
+    aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
+    aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
+    aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
+    mWriter.setLayerPerFrameMetadata(mPrimaryDisplay, layer, aidlMetadata);
+    execute();
+
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
+        EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+        return;
+    }
+
+    EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints) {
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_Delayed) {
+    Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000,  // 300ms
+                                         .refreshMiss = false});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, getDisplayVsyncPeriod) {
+    for (VtsDisplay& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+        for (int32_t config : configs) {
+            int32_t expectedVsyncPeriodNanos = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::VSYNC_PERIOD,
+                                                      &expectedVsyncPeriodNanos)
+                                .isOk());
+
+            VsyncPeriodChangeTimeline timeline;
+            VsyncPeriodChangeConstraints constraints;
+
+            constraints.desiredTimeNanos = systemTime();
+            constraints.seamlessRequired = false;
+            EXPECT_TRUE(mComposerClient
+                                ->setActiveConfigWithConstraints(display.get(), config, constraints,
+                                                                 &timeline)
+                                .isOk());
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(display, &timeline);
+            }
+            waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
+                                     expectedVsyncPeriodNanos);
+
+            int32_t vsyncPeriodNanos;
+            int retryCount = 100;
+            do {
+                std::this_thread::sleep_for(10ms);
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                --retryCount;
+            } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
+
+            EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+            // Make sure that the vsync period stays the same if the active config is not
+            // changed.
+            auto timeout = 1ms;
+            for (int i = 0; i < 10; i++) {
+                std::this_thread::sleep_for(timeout);
+                timeout *= 2;
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+    VsyncPeriodChangeTimeline timeline;
+    VsyncPeriodChangeConstraints constraints;
+
+    constraints.seamlessRequired = true;
+    constraints.desiredTimeNanos = systemTime();
+
+    for (VtsDisplay& display : mDisplays) {
+        forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+            int32_t configGroup1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config1,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup1)
+                                .isOk());
+            int32_t configGroup2;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config2,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup2)
+                                .isOk());
+            if (configGroup1 != configGroup2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+                EXPECT_EQ(IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
+                          setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                  .getServiceSpecificError());
+            }
+        });
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerAidlCommandTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlTest,
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index bb5f3f1..df038db 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,17 +28,51 @@
     defaults: ["hidl_defaults"],
     srcs: [
         "GraphicsComposerCallback.cpp",
+        "ReadbackVts.cpp",
+        "RenderEngineVts.cpp",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+        "libarect",
         "libgtest",
         "libbase",
+        "libfmq",
+        "libsync",
+        "libmath",
+        "libaidlcommonsupport",
+        "libnativewindow",
+        "librenderengine",
+        "libshaders",
+        "libtonemap",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@2.1-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libhidlbase",
+        "libui",
+        "android.hardware.graphics.composer3-V1-ndk",
+    ],
+    export_static_lib_headers: [
+        "android.hardware.graphics.mapper@2.1-vts",
+        "librenderengine",
     ],
     cflags: [
         "-O0",
         "-g",
         "-DLOG_TAG=\"ComposerVts\"",
+        "-Wconversion",
+    ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
index daf9924..307fe15 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
@@ -125,12 +125,4 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
-::ndk::SpAIBinder GraphicsComposerCallback::asBinder() {
-    return nullptr;
-}
-
-bool GraphicsComposerCallback::isRemote() {
-    return true;
-}
-
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
new file mode 100644
index 0000000..a6954b4
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
@@ -0,0 +1,356 @@
+/**
+ * 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.
+ */
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include "include/ReadbackVts.h"
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include "include/RenderEngineVts.h"
+#include "renderengine/ExternalTexture.h"
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
+const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
+                                                           common::Dataspace::DISPLAY_P3};
+
+void TestLayer::write(CommandWriterBase& writer) {
+    writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
+    writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
+    writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
+    writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
+    writer.setLayerTransform(mDisplay, mLayer, mTransform);
+    writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
+    writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
+}
+
+std::string ReadbackHelper::getColorModeString(ColorMode mode) {
+    switch (mode) {
+        case ColorMode::SRGB:
+            return {"SRGB"};
+        case ColorMode::DISPLAY_P3:
+            return {"DISPLAY_P3"};
+        default:
+            return {"Unsupported color mode for readback"};
+    }
+}
+
+std::string ReadbackHelper::getDataspaceString(common::Dataspace dataspace) {
+    switch (dataspace) {
+        case common::Dataspace::SRGB:
+            return {"SRGB"};
+        case common::Dataspace::DISPLAY_P3:
+            return {"DISPLAY_P3"};
+        case common::Dataspace::UNKNOWN:
+            return {"UNKNOWN"};
+        default:
+            return {"Unsupported dataspace for readback"};
+    }
+}
+
+Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
+    switch (mode) {
+        case ColorMode::DISPLAY_P3:
+            return Dataspace::DISPLAY_P3;
+        case ColorMode::SRGB:
+        default:
+            return common::Dataspace::UNKNOWN;
+    }
+}
+
+LayerSettings TestLayer::toRenderEngineLayerSettings() {
+    LayerSettings layerSettings;
+
+    layerSettings.alpha = ::android::half(mAlpha);
+    layerSettings.disableBlending = mBlendMode == BlendMode::NONE;
+    layerSettings.geometry.boundaries = ::android::FloatRect(
+            static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
+            static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
+
+    const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
+            (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
+                     ? static_cast<float>(-mDisplayFrame.right)
+                     : 0.0f),
+            (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
+                     ? static_cast<float>(-mDisplayFrame.bottom)
+                     : 0.0f),
+            0.0f, 1.0f));
+
+    const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
+            static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
+                                                                                         : 1.0f,
+            static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
+                                                                                         : 1.0f,
+            1.0f, 1.0f));
+
+    layerSettings.geometry.positionTransform = scale * translation;
+
+    return layerSettings;
+}
+
+int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
+    switch (pixelFormat) {
+        case common::PixelFormat::RGBA_8888:
+            return 4;
+        case common::PixelFormat::RGB_888:
+            return 3;
+        default:
+            return -1;
+    }
+}
+
+void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+                                common::PixelFormat pixelFormat,
+                                std::vector<Color> desiredPixelColors) {
+    ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
+                pixelFormat == common::PixelFormat::RGBA_8888);
+    int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+    ASSERT_NE(-1, bytesPerPixel);
+    for (int row = 0; row < height; row++) {
+        for (int col = 0; col < width; col++) {
+            auto pixel = row * static_cast<int32_t>(width) + col;
+            Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
+
+            int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
+            uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+            pixelColor[0] = static_cast<uint8_t>(srcColor.r);
+            pixelColor[1] = static_cast<uint8_t>(srcColor.g);
+            pixelColor[2] = static_cast<uint8_t>(srcColor.b);
+
+            if (bytesPerPixel == 4) {
+                pixelColor[3] = static_cast<uint8_t>(srcColor.a);
+            }
+        }
+    }
+}
+
+void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+                                 int32_t displayWidth) {
+    for (int row = 0; row < height; row++) {
+        for (int col = 0; col < width; col++) {
+            int pixel = row * displayWidth + col;
+            expectedColors[static_cast<size_t>(pixel)] = BLACK;
+        }
+    }
+}
+
+void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
+                                    Color color) {
+    for (int row = area.top; row < area.bottom; row++) {
+        for (int col = area.left; col < area.right; col++) {
+            int pixel = row * stride + col;
+            expectedColors[static_cast<size_t>(pixel)] = color;
+        }
+    }
+}
+
+bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
+                                       const common::Dataspace& dataspace) {
+    if (pixelFormat != common::PixelFormat::RGB_888 &&
+        pixelFormat != common::PixelFormat::RGBA_8888) {
+        return false;
+    }
+    if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
+        return false;
+    }
+    return true;
+}
+
+void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
+                                         const int32_t stride, const uint32_t width,
+                                         const uint32_t height, common::PixelFormat pixelFormat) {
+    const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+    ASSERT_NE(-1, bytesPerPixel);
+    for (int row = 0; row < height; row++) {
+        for (int col = 0; col < width; col++) {
+            auto pixel = row * static_cast<int32_t>(width) + col;
+            int offset = (row * stride + col) * bytesPerPixel;
+            uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+
+            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].r),
+                      pixelColor[0]);
+            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].g),
+                      pixelColor[1]);
+            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].b),
+                      pixelColor[2]);
+        }
+    }
+}
+
+ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
+                               const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+                               int32_t width, int32_t height, common::PixelFormat pixelFormat,
+                               common::Dataspace dataspace) {
+    mDisplay = display;
+
+    mComposerClient = client;
+    mGraphicBuffer = graphicBuffer;
+
+    mPixelFormat = pixelFormat;
+    mDataspace = dataspace;
+
+    mWidth = static_cast<uint32_t>(width);
+    mHeight = static_cast<uint32_t>(height);
+    mLayerCount = 1;
+    mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                                   static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
+
+    mAccessRegion.top = 0;
+    mAccessRegion.left = 0;
+    mAccessRegion.right = static_cast<int32_t>(width);
+    mAccessRegion.bottom = static_cast<int32_t>(height);
+}
+
+::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocate() {
+    return ::android::sp<::android::GraphicBuffer>::make(
+            mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
+            "ReadbackVts");
+}
+
+void ReadbackBuffer::setReadbackBuffer() {
+    mGraphicBuffer = allocate();
+    ASSERT_NE(nullptr, mGraphicBuffer);
+    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+    aidl::android::hardware::common::NativeHandle bufferHandle =
+            ::android::dupToAidl(mGraphicBuffer->handle);
+    ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+    EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
+}
+
+void ReadbackBuffer::checkReadbackBuffer(std::vector<Color> expectedColors) {
+    // lock buffer for reading
+    ndk::ScopedFileDescriptor fenceHandle;
+    EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle).isOk());
+
+    int outBytesPerPixel;
+    int outBytesPerStride;
+    auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, nullptr, fenceHandle.get(),
+                                            &outBytesPerPixel, &outBytesPerStride);
+    EXPECT_EQ(::android::OK, status);
+    ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+    ReadbackHelper::compareColorBuffers(expectedColors, mGraphicBuffer.get(),
+                                        static_cast<int32_t>(mStride), mWidth, mHeight,
+                                        mPixelFormat);
+    status = mGraphicBuffer->unlock();
+    EXPECT_EQ(::android::OK, status);
+}
+
+void TestColorLayer::write(CommandWriterBase& writer) {
+    TestLayer::write(writer);
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
+    writer.setLayerColor(mDisplay, mLayer, mColor);
+}
+
+LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
+    LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+
+    layerSettings.source.solidColor =
+            ::android::half3(static_cast<::android::half>(mColor.r) / 255.0,
+                             static_cast<::android::half>(mColor.g) / 255.0,
+                             static_cast<::android::half>(mColor.b) / 255.0);
+    layerSettings.alpha =
+            mAlpha * static_cast<float>((static_cast<::android::half>(mColor.a) / 255.0));
+    return layerSettings;
+}
+
+TestBufferLayer::TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
+                                 const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+                                 TestRenderEngine& renderEngine, int64_t display, uint32_t width,
+                                 uint32_t height, common::PixelFormat format,
+                                 Composition composition)
+    : TestLayer{client, display}, mRenderEngine(renderEngine) {
+    mGraphicBuffer = graphicBuffer;
+    mComposition = composition;
+    mWidth = width;
+    mHeight = height;
+    mLayerCount = 1;
+    mPixelFormat = format;
+    mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+              static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+              static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
+              static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
+
+    mAccessRegion.top = 0;
+    mAccessRegion.left = 0;
+    mAccessRegion.right = static_cast<int32_t>(width);
+    mAccessRegion.bottom = static_cast<int32_t>(height);
+
+    setSourceCrop({0, 0, (float)width, (float)height});
+}
+
+void TestBufferLayer::write(CommandWriterBase& writer) {
+    TestLayer::write(writer);
+    writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
+    writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
+    if (mGraphicBuffer->handle != nullptr)
+        writer.setLayerBuffer(mDisplay, mLayer, 0, mGraphicBuffer->handle, mFillFence);
+}
+
+LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
+    LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+    layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>(
+            ::android::sp<::android::GraphicBuffer>::make(
+                    mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
+                    static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride),
+            mRenderEngine.getInternalRenderEngine(),
+            ::android::renderengine::ExternalTexture::Usage::READABLE);
+
+    layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
+
+    const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
+    const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
+    const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
+    const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
+
+    layerSettings.source.buffer.textureTransform =
+            ::android::mat4::translate(::android::vec4(translateX, translateY, 0, 1)) *
+            ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0, 1.0));
+
+    return layerSettings;
+}
+
+void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
+    void* bufData;
+    auto status = mGraphicBuffer->lock(mUsage, &bufData);
+    EXPECT_EQ(::android::OK, status);
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData,
+                                                       mPixelFormat, expectedColors));
+    EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+}
+
+void TestBufferLayer::setBuffer(std::vector<Color> colors) {
+    mGraphicBuffer->reallocate(mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat),
+                               mLayerCount, mUsage);
+    ASSERT_NE(nullptr, mGraphicBuffer);
+    ASSERT_NE(nullptr, mGraphicBuffer->handle);
+    ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+}
+
+void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) {
+    writer.setLayerDataspace(mDisplay, mLayer, dataspace);
+}
+
+void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) {
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
+}
+
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
new file mode 100644
index 0000000..50ce462
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/RenderEngineVts.h"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::hardware::graphics::mapper::V2_1::IMapper;
+using ::android::renderengine::DisplaySettings;
+using ::android::renderengine::LayerSettings;
+using ::android::renderengine::RenderEngineCreationArgs;
+
+TestRenderEngine::TestRenderEngine(const RenderEngineCreationArgs& args) {
+    mFormat = static_cast<common::PixelFormat>(args.pixelFormat);
+    mRenderEngine = ::android::renderengine::RenderEngine::create(args);
+}
+
+TestRenderEngine::~TestRenderEngine() {
+    mRenderEngine.release();
+}
+
+void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
+    sort(layers.begin(), layers.end(),
+         [](const std::shared_ptr<TestLayer>& lhs, const std::shared_ptr<TestLayer>& rhs) -> bool {
+             return lhs->getZOrder() < rhs->getZOrder();
+         });
+
+    if (!mCompositionLayers.empty()) {
+        mCompositionLayers.clear();
+    }
+    for (auto& layer : layers) {
+        LayerSettings settings = layer->toRenderEngineLayerSettings();
+        mCompositionLayers.push_back(settings);
+    }
+}
+
+void TestRenderEngine::initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
+                                         uint64_t usage) {
+    mGraphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
+            width, height, static_cast<int32_t>(mFormat), layerCount, usage);
+}
+
+void TestRenderEngine::drawLayers() {
+    ::android::base::unique_fd bufferFence;
+
+    std::vector<::android::renderengine::LayerSettings> compositionLayers;
+    compositionLayers.reserve(mCompositionLayers.size());
+    std::transform(mCompositionLayers.begin(), mCompositionLayers.end(),
+                   std::back_insert_iterator(compositionLayers),
+                   [](::android::renderengine::LayerSettings& settings)
+                           -> ::android::renderengine::LayerSettings { return settings; });
+    auto texture = std::make_shared<::android::renderengine::ExternalTexture>(
+            mGraphicBuffer, *mRenderEngine,
+            ::android::renderengine::ExternalTexture::Usage::WRITEABLE);
+    auto [status, readyFence] = mRenderEngine
+                                        ->drawLayers(mDisplaySettings, compositionLayers, texture,
+                                                     true, std::move(bufferFence))
+                                        .get();
+    int fd = readyFence.release();
+    if (fd != -1) {
+        ASSERT_EQ(0, sync_wait(fd, -1));
+        ASSERT_EQ(0, close(fd));
+    }
+}
+
+void TestRenderEngine::checkColorBuffer(std::vector<Color>& expectedColors) {
+    void* bufferData;
+    ASSERT_EQ(0,
+              mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()), &bufferData));
+    ReadbackHelper::compareColorBuffers(
+            expectedColors, bufferData, static_cast<int32_t>(mGraphicBuffer->getStride()),
+            mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(), mFormat);
+    ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
+}
+
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
index 9afc72f..c359d5e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
@@ -15,16 +15,21 @@
  */
 #pragma once
 
-#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
+#include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h>
 #include <android-base/thread_annotations.h>
 #include <mutex>
 #include <unordered_set>
 
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 namespace aidl::android::hardware::graphics::composer3::vts {
 
-// IComposerCallback to be installed with IComposerClient::registerCallback.
-class GraphicsComposerCallback : public IComposerCallback {
+class GraphicsComposerCallback : public BnComposerCallback {
   public:
     void setVsyncAllowed(bool allowed);
 
@@ -53,9 +58,6 @@
             const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
                     in_updatedTimeline) override;
 
-    ::ndk::SpAIBinder asBinder() override;
-    bool isRemote() override;
-
     mutable std::mutex mMutex;
     // the set of all currently connected displays
     std::unordered_set<int64_t> mDisplays GUARDED_BY(mMutex);
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
new file mode 100644
index 0000000..d40e3d2
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <GraphicsComposerCallback.h>
+#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/composer3/command-buffer.h>
+#include <mapper-vts/2.1/MapperVts.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+
+#include <memory>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::renderengine::LayerSettings;
+using common::Dataspace;
+using common::PixelFormat;
+using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
+
+static const Color BLACK = {0, 0, 0, static_cast<int8_t>(0xff)};
+static const Color RED = {static_cast<int8_t>(0xff), 0, 0, static_cast<int8_t>(0xff)};
+static const Color TRANSLUCENT_RED = {static_cast<int8_t>(0xff), 0, 0, 0x33};
+static const Color GREEN = {0, static_cast<int8_t>(0xff), 0, static_cast<int8_t>(0xff)};
+static const Color BLUE = {0, 0, static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
+static const Color WHITE = {static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+                            static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
+
+class TestRenderEngine;
+
+class TestLayer {
+  public:
+    TestLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
+        : mDisplay(display), mComposerClient(client) {
+        client->createLayer(display, kBufferSlotCount, &mLayer);
+    }
+
+    // ComposerClient will take care of destroying layers, no need to explicitly
+    // call destroyLayers here
+    virtual ~TestLayer(){};
+
+    virtual void write(CommandWriterBase& writer);
+    virtual LayerSettings toRenderEngineLayerSettings();
+
+    void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
+    void setSourceCrop(FRect crop) { mSourceCrop = crop; }
+    void setZOrder(uint32_t z) { mZOrder = z; }
+
+    void setSurfaceDamage(std::vector<Rect> surfaceDamage) {
+        mSurfaceDamage = std::move(surfaceDamage);
+    }
+
+    void setTransform(Transform transform) { mTransform = transform; }
+    void setAlpha(float alpha) { mAlpha = alpha; }
+    void setBlendMode(BlendMode blendMode) { mBlendMode = blendMode; }
+
+    BlendMode getBlendMode() const { return mBlendMode; }
+
+    uint32_t getZOrder() const { return mZOrder; }
+
+    float getAlpha() const { return mAlpha; }
+
+    int64_t getLayer() const { return mLayer; }
+
+  protected:
+    int64_t mDisplay;
+    int64_t mLayer;
+    Rect mDisplayFrame = {0, 0, 0, 0};
+    std::vector<Rect> mSurfaceDamage;
+    Transform mTransform = static_cast<Transform>(0);
+    FRect mSourceCrop = {0, 0, 0, 0};
+    static constexpr uint32_t kBufferSlotCount = 64;
+    float mAlpha = 1.0;
+    BlendMode mBlendMode = BlendMode::NONE;
+    uint32_t mZOrder = 0;
+
+  private:
+    std::shared_ptr<IComposerClient> const mComposerClient;
+};
+
+class TestColorLayer : public TestLayer {
+  public:
+    TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
+        : TestLayer{client, display} {}
+
+    void write(CommandWriterBase& writer) override;
+
+    LayerSettings toRenderEngineLayerSettings() override;
+
+    void setColor(Color color) { mColor = color; }
+
+  private:
+    Color mColor = WHITE;
+};
+
+class TestBufferLayer : public TestLayer {
+  public:
+    TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
+                    const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+                    TestRenderEngine& renderEngine, int64_t display, uint32_t width,
+                    uint32_t height, common::PixelFormat format,
+                    Composition composition = Composition::DEVICE);
+
+    void write(CommandWriterBase& writer) override;
+
+    LayerSettings toRenderEngineLayerSettings() override;
+
+    void fillBuffer(std::vector<Color>& expectedColors);
+
+    void setBuffer(std::vector<Color> colors);
+
+    void setDataspace(Dataspace dataspace, CommandWriterBase& writer);
+
+    void setToClientComposition(CommandWriterBase& writer);
+
+    uint32_t getWidth() const { return mWidth; }
+
+    uint32_t getHeight() const { return mHeight; }
+
+    ::android::Rect getAccessRegion() const { return mAccessRegion; }
+
+    uint32_t getLayerCount() const { return mLayerCount; }
+
+  protected:
+    Composition mComposition;
+    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+    TestRenderEngine& mRenderEngine;
+    int32_t mFillFence;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mLayerCount;
+    PixelFormat mPixelFormat;
+    uint32_t mUsage;
+    uint32_t mStride;
+    ::android::Rect mAccessRegion;
+};
+
+class ReadbackHelper {
+  public:
+    static std::string getColorModeString(ColorMode mode);
+
+    static std::string getDataspaceString(Dataspace dataspace);
+
+    static Dataspace getDataspaceForColorMode(ColorMode mode);
+
+    static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
+
+    static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+                           PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
+
+    static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+                            int32_t displayWidth);
+
+    static void fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
+                               Color color);
+
+    static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace);
+
+    static const std::vector<ColorMode> colorModes;
+    static const std::vector<Dataspace> dataspaces;
+
+    static void compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
+                                    const int32_t stride, const uint32_t width,
+                                    const uint32_t height, PixelFormat pixelFormat);
+};
+
+class ReadbackBuffer {
+  public:
+    ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
+                   const ::android::sp<::android::GraphicBuffer>& graphicBuffer, int32_t width,
+                   int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace);
+
+    void setReadbackBuffer();
+
+    void checkReadbackBuffer(std::vector<Color> expectedColors);
+
+    ::android::sp<::android::GraphicBuffer> allocate();
+
+  protected:
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mLayerCount;
+    uint32_t mUsage;
+    uint32_t mStride;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+    int64_t mDisplay;
+    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+    std::shared_ptr<IComposerClient> mComposerClient;
+    ::android::Rect mAccessRegion;
+    native_handle_t mBufferHandle;
+};
+
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
new file mode 100644
index 0000000..2798e09
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <ReadbackVts.h>
+#include <mapper-vts/2.1/MapperVts.h>
+#include <math/half.h>
+#include <math/vec3.h>
+#include <renderengine/ExternalTexture.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::hardware::graphics::mapper::V2_1::IMapper;
+using ::android::renderengine::DisplaySettings;
+using ::android::renderengine::ExternalTexture;
+using ::android::renderengine::RenderEngineCreationArgs;
+
+class TestRenderEngine {
+  public:
+    static constexpr uint32_t sMaxFrameBufferAcquireBuffers = 2;
+
+    TestRenderEngine(const RenderEngineCreationArgs& args);
+    ~TestRenderEngine();
+
+    void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
+    void initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint64_t usage);
+    void setDisplaySettings(DisplaySettings& displaySettings) {
+        mDisplaySettings = displaySettings;
+    };
+    void drawLayers();
+    void checkColorBuffer(std::vector<Color>& expectedColors);
+
+    ::android::renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; }
+
+  private:
+    common::PixelFormat mFormat;
+    std::vector<::android::renderengine::LayerSettings> mCompositionLayers;
+    std::unique_ptr<::android::renderengine::RenderEngine> mRenderEngine;
+    std::vector<::android::renderengine::LayerSettings> mRenderLayers;
+    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+
+    DisplaySettings mDisplaySettings;
+};
+
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
index d02cf9c..bdf97ca 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
@@ -19,15 +19,16 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
 #include <inttypes.h>
 #include <string.h>
 
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
 #include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
 #include <aidl/android/hardware/graphics/composer3/Color.h>
-#include <aidl/android/hardware/graphics/composer3/Command.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/FloatColor.h>
 #include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
@@ -36,39 +37,29 @@
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
 
+#include <aidl/android/hardware/graphics/composer3/command/CommandPayload.h>
+#include <aidl/android/hardware/graphics/composer3/command/CommandResultPayload.h>
+
 #include <aidl/android/hardware/graphics/common/ColorTransform.h>
 #include <aidl/android/hardware/graphics/common/FRect.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/common/Transform.h>
 
-#include <fmq/AidlMessageQueue.h>
 #include <log/log.h>
 #include <sync/sync.h>
 
 #include <aidlcommonsupport/NativeHandle.h>
 
+using aidl::android::hardware::graphics::common::BlendMode;
 using aidl::android::hardware::graphics::common::ColorTransform;
 using aidl::android::hardware::graphics::common::Dataspace;
 using aidl::android::hardware::graphics::common::FRect;
 using aidl::android::hardware::graphics::common::Rect;
 using aidl::android::hardware::graphics::common::Transform;
 
-using aidl::android::hardware::graphics::composer3::BlendMode;
-using aidl::android::hardware::graphics::composer3::ClientTargetProperty;
-using aidl::android::hardware::graphics::composer3::Color;
-using aidl::android::hardware::graphics::composer3::Command;
-using aidl::android::hardware::graphics::composer3::Composition;
-using aidl::android::hardware::graphics::composer3::FloatColor;
-using aidl::android::hardware::graphics::composer3::HandleIndex;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadata;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob;
+using namespace aidl::android::hardware::graphics::composer3;
 
 using aidl::android::hardware::common::NativeHandle;
-using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
-using android::AidlMessageQueue;
-using CommandQueueType = AidlMessageQueue<int32_t, SynchronizedReadWrite>;
-using aidl::android::hardware::common::fmq::MQDescriptor;
-using DescriptorType = MQDescriptor<int32_t, SynchronizedReadWrite>;
 
 namespace aidl::android::hardware::graphics::composer3 {
 
@@ -76,820 +67,541 @@
 // units of uint32_t's.
 class CommandWriterBase {
   public:
-    CommandWriterBase(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
-        mData = std::make_unique<int32_t[]>(mDataMaxSize);
-        reset();
-    }
+    CommandWriterBase() { reset(); }
 
     virtual ~CommandWriterBase() { reset(); }
 
     void reset() {
-        mDataWritten = 0;
-        mCommandEnd = 0;
-
-        // handles in mDataHandles are owned by the caller
-        mDataHandles.clear();
-
-        // handles in mTemporaryHandles are owned by the writer
-        for (auto handle : mTemporaryHandles) {
-            native_handle_close(handle);
-            native_handle_delete(handle);
-        }
-        mTemporaryHandles.clear();
+        mDisplayCommand.reset();
+        mLayerCommand.reset();
+        mCommands.clear();
+        mCommandsResults.clear();
     }
 
-    Command getCommand(uint32_t offset) {
-        uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
-        return static_cast<Command>(val & static_cast<uint32_t>(Command::OPCODE_MASK));
+    void setError(int32_t index, int32_t errorCode) {
+        command::Error error;
+        error.commandIndex = index;
+        error.errorCode = errorCode;
+        mCommandsResults.emplace_back(std::move(error));
     }
 
-    bool writeQueue(bool* outQueueChanged, int32_t* outCommandLength,
-                    std::vector<NativeHandle>* outCommandHandles) {
-        if (mDataWritten == 0) {
-            *outQueueChanged = false;
-            *outCommandLength = 0;
-            outCommandHandles->clear();
-            return true;
-        }
-
-        // After data are written to the queue, it may not be read by the
-        // remote reader when
-        //
-        //  - the writer does not send them (because of other errors)
-        //  - the hwbinder transaction fails
-        //  - the reader does not read them (because of other errors)
-        //
-        // Discard the stale data here.
-        size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
-        if (staleDataSize > 0) {
-            ALOGW("discarding stale data from message queue");
-            CommandQueueType::MemTransaction tx;
-            if (mQueue->beginRead(staleDataSize, &tx)) {
-                mQueue->commitRead(staleDataSize);
-            }
-        }
-
-        // write data to queue, optionally resizing it
-        if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
-            if (!mQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to write commands to message queue");
-                return false;
-            }
-
-            *outQueueChanged = false;
-        } else {
-            auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
-            if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to prepare a new message queue ");
-                return false;
-            }
-
-            mQueue = std::move(newQueue);
-            *outQueueChanged = true;
-        }
-
-        *outCommandLength = mDataWritten;
-        *outCommandHandles = std::move(mDataHandles);
-
-        return true;
+    void setPresentOrValidateResult(int64_t display, command::PresentOrValidate::Result result) {
+        command::PresentOrValidate presentOrValidate;
+        presentOrValidate.display = display;
+        presentOrValidate.result = result;
+        mCommandsResults.emplace_back(std::move(presentOrValidate));
     }
 
-    DescriptorType getMQDescriptor() const {
-        return (mQueue) ? mQueue->dupeDesc() : DescriptorType{};
-    }
-
-    static constexpr uint16_t kSelectDisplayLength = 2;
-    void selectDisplay(int64_t display) {
-        beginCommand(Command::SELECT_DISPLAY, kSelectDisplayLength);
-        write64(display);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSelectLayerLength = 2;
-    void selectLayer(int64_t layer) {
-        beginCommand(Command::SELECT_LAYER, kSelectLayerLength);
-        write64(layer);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetErrorLength = 2;
-    void setError(uint32_t location, int32_t error) {
-        beginCommand(Command::SET_ERROR, kSetErrorLength);
-        write(location);
-        writeSigned(error);
-        endCommand();
-    }
-
-    static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
-    void setPresentOrValidateResult(uint32_t state) {
-        beginCommand(Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
-                     kPresentOrValidateDisplayResultLength);
-        write(state);
-        endCommand();
-    }
-
-    void setChangedCompositionTypes(const std::vector<int64_t>& layers,
+    void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers,
                                     const std::vector<Composition>& types) {
-        size_t totalLayers = std::min(layers.size(), types.size());
-        size_t currentLayer = 0;
+        command::ChangedCompositionTypes changedCompositionTypes;
+        changedCompositionTypes.display = display;
+        changedCompositionTypes.layers.reserve(layers.size());
+        for (int i = 0; i < layers.size(); i++) {
+            auto layer = command::ChangedCompositionTypes::Layer{.layer = layers[i],
+                                                                 .composition = types[i]};
+            changedCompositionTypes.layers.emplace_back(std::move(layer));
+        }
+        mCommandsResults.emplace_back(std::move(changedCompositionTypes));
+    }
 
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
+    void setDisplayRequests(int64_t display, int32_t displayRequestMask,
+                            const std::vector<int64_t>& layers,
+                            const std::vector<int32_t>& layerRequestMasks) {
+        command::DisplayRequest displayRequest;
+        displayRequest.display = display;
+        displayRequest.mask = displayRequestMask;
+        displayRequest.layerRequests.reserve(layers.size());
+        for (int i = 0; i < layers.size(); i++) {
+            auto layerRequest = command::DisplayRequest::LayerRequest{.layer = layers[i],
+                                                                      .mask = layerRequestMasks[i]};
+            displayRequest.layerRequests.emplace_back(std::move(layerRequest));
+        }
+        mCommandsResults.emplace_back(std::move(displayRequest));
+    }
 
-            beginCommand(Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeSigned(static_cast<int32_t>(types[currentLayer + i]));
+    void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) {
+        if (presentFence.get() >= 0) {
+            command::PresentFence presentFenceCommand;
+            presentFenceCommand.fence = std::move(presentFence);
+            presentFenceCommand.display = display;
+            mCommandsResults.emplace_back(std::move(presentFenceCommand));
+        } else {
+            ALOGW("%s: invalid present fence %d", __func__, presentFence.get());
+        }
+    }
+
+    void setReleaseFences(int64_t display, const std::vector<int64_t>& layers,
+                          std::vector<::ndk::ScopedFileDescriptor> releaseFences) {
+        command::ReleaseFences releaseFencesCommand;
+        releaseFencesCommand.display = display;
+        for (int i = 0; i < layers.size(); i++) {
+            if (releaseFences[i].get() >= 0) {
+                command::ReleaseFences::Layer layer;
+                layer.layer = layers[i];
+                layer.fence = std::move(releaseFences[i]);
+                releaseFencesCommand.layers.emplace_back(std::move(layer));
+            } else {
+                ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get());
             }
-            endCommand();
-
-            currentLayer += count;
         }
+        mCommandsResults.emplace_back(std::move(releaseFencesCommand));
     }
 
-    void setDisplayRequests(uint32_t displayRequestMask, const std::vector<int64_t>& layers,
-                            const std::vector<uint32_t>& layerRequestMasks) {
-        size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
-        size_t currentLayer = 0;
+    void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty,
+                                 float whitePointNits) {
+        command::ClientTargetPropertyWithNits clientTargetPropertyWithNits;
+        clientTargetPropertyWithNits.display = display;
+        clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty;
+        clientTargetPropertyWithNits.whitePointNits = whitePointNits;
+        mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits));
+    }
 
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
+    void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) {
+        command::ColorTransformPayload colorTransformPayload;
+        colorTransformPayload.matrix.assign(matrix, matrix + 16);
+        colorTransformPayload.hint = hint;
+        getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload));
+    }
 
-            beginCommand(Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
-            write(displayRequestMask);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
-            }
-            endCommand();
+    void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
+                         int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+        command::ClientTarget clientTargetCommand;
+        clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+        clientTargetCommand.dataspace = dataspace;
+        clientTargetCommand.damage.assign(damage.begin(), damage.end());
+        getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
+    }
 
-            currentLayer += count;
+    void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
+                         int releaseFence) {
+        getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
+                getBuffer(slot, buffer, releaseFence));
+    }
+
+    void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; }
+
+    void presentOrvalidateDisplay(int64_t display) {
+        getDisplayCommand(display).presentOrValidateDisplay = true;
+    }
+
+    void acceptDisplayChanges(int64_t display) {
+        getDisplayCommand(display).acceptDisplayChanges = true;
+    }
+
+    void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }
+
+    void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
+        common::Point cursorPosition;
+        cursorPosition.x = x;
+        cursorPosition.y = y;
+        getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
+    }
+
+    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
+                        const native_handle_t* buffer, int acquireFence) {
+        getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+    }
+
+    void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
+        getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
+    }
+
+    void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
+        command::ParcelableBlendMode parcelableBlendMode;
+        parcelableBlendMode.blendMode = mode;
+        getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
+    }
+
+    void setLayerColor(int64_t display, int64_t layer, Color color) {
+        getLayerCommand(display, layer).color.emplace(std::move(color));
+    }
+
+    void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
+        command::ParcelableComposition compositionPayload;
+        compositionPayload.composition = type;
+        getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
+    }
+
+    void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
+        command::ParcelableDataspace dataspacePayload;
+        dataspacePayload.dataspace = dataspace;
+        getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
+    }
+
+    void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
+        getLayerCommand(display, layer).displayFrame.emplace(frame);
+    }
+
+    void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
+        command::PlaneAlpha planeAlpha;
+        planeAlpha.alpha = alpha;
+        getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
+    }
+
+    void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
+        NativeHandle handle;
+        if (stream) handle = ::android::dupToAidl(stream);
+        getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
+    }
+
+    void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
+        getLayerCommand(display, layer).sourceCrop.emplace(crop);
+    }
+
+    void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
+        command::ParcelableTransform transformPayload;
+        transformPayload.transform = transform;
+        getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
+    }
+
+    void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
+        getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
+    }
+
+    void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
+        command::ZOrder zorder;
+        zorder.z = z;
+        getLayerCommand(display, layer).z.emplace(std::move(zorder));
+    }
+
+    void setLayerPerFrameMetadata(int64_t display, int64_t layer,
+                                  const std::vector<PerFrameMetadata>& metadataVec) {
+        getLayerCommand(display, layer)
+                .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
+    }
+
+    void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
+        getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
+    }
+
+    void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
+                                       const std::vector<PerFrameMetadataBlob>& metadata) {
+        getLayerCommand(display, layer)
+                .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
+    }
+
+    void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) {
+        getLayerCommand(display, layer).floatColor.emplace(color);
+    }
+
+    void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key,
+                                 const bool mandatory, const std::vector<uint8_t>& value) {
+        command::GenericMetadata metadata;
+        metadata.key.name = key;
+        metadata.key.mandatory = mandatory;
+        metadata.value.assign(value.begin(), value.end());
+        getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata));
+    }
+
+    const std::vector<command::CommandPayload>& getPendingCommands() {
+        if (mLayerCommand.has_value()) {
+            mCommands.emplace_back(std::move(*mLayerCommand));
+            mLayerCommand.reset();
         }
-    }
-
-    static constexpr uint16_t kSetPresentFenceLength = 1;
-    void setPresentFence(int presentFence) {
-        beginCommand(Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
-        writeFence(presentFence);
-        endCommand();
-    }
-
-    void setReleaseFences(const std::vector<int64_t>& layers,
-                          const std::vector<int>& releaseFences) {
-        size_t totalLayers = std::min(layers.size(), releaseFences.size());
-        size_t currentLayer = 0;
-
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
-
-            beginCommand(Command::SET_RELEASE_FENCES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeFence(releaseFences[currentLayer + i]);
-            }
-            endCommand();
-
-            currentLayer += count;
+        if (mDisplayCommand.has_value()) {
+            mCommands.emplace_back(std::move(*mDisplayCommand));
+            mDisplayCommand.reset();
         }
+        return mCommands;
     }
-
-    static constexpr uint16_t kSetColorTransformLength = 17;
-    void setColorTransform(const float* matrix, ColorTransform hint) {
-        beginCommand(Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        writeSigned(static_cast<int32_t>(hint));
-        endCommand();
-    }
-
-    void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
-                         Dataspace dataspace, const std::vector<Rect>& damage) {
-        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
-                                damage);
-    }
-
-    static constexpr uint16_t kSetOutputBufferLength = 3;
-    void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, int releaseFence) {
-        beginCommand(Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(releaseFence);
-        endCommand();
-    }
-
-    static constexpr uint16_t kValidateDisplayLength = 0;
-    void validateDisplay() {
-        beginCommand(Command::VALIDATE_DISPLAY, kValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
-    void presentOrvalidateDisplay() {
-        beginCommand(Command::PRESENT_OR_VALIDATE_DISPLAY, kPresentOrValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kAcceptDisplayChangesLength = 0;
-    void acceptDisplayChanges() {
-        beginCommand(Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentDisplayLength = 0;
-    void presentDisplay() {
-        beginCommand(Command::PRESENT_DISPLAY, kPresentDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCursorPositionLength = 2;
-    void setLayerCursorPosition(int32_t x, int32_t y) {
-        beginCommand(Command::SET_LAYER_CURSOR_POSITION, kSetLayerCursorPositionLength);
-        writeSigned(x);
-        writeSigned(y);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBufferLength = 3;
-    void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, int acquireFence) {
-        beginCommand(Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(acquireFence);
-        endCommand();
-    }
-
-    void setLayerSurfaceDamage(const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? damage.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_SURFACE_DAMAGE, length);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // layer is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBlendModeLength = 1;
-    void setLayerBlendMode(BlendMode mode) {
-        beginCommand(Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
-        writeSigned(static_cast<int32_t>(mode));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorLength = 1;
-    void setLayerColor(Color color) {
-        beginCommand(Command::SET_LAYER_COLOR, kSetLayerColorLength);
-        writeColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
-    void setLayerCompositionType(Composition type) {
-        beginCommand(Command::SET_LAYER_COMPOSITION_TYPE, kSetLayerCompositionTypeLength);
-        writeSigned(static_cast<int32_t>(type));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerDataspaceLength = 1;
-    void setLayerDataspace(Dataspace dataspace) {
-        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
-    }
-
-    static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
-    void setLayerDisplayFrame(const Rect& frame) {
-        beginCommand(Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
-        writeRect(frame);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
-    void setLayerPlaneAlpha(float alpha) {
-        beginCommand(Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
-        writeFloat(alpha);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
-    void setLayerSidebandStream(const native_handle_t* stream) {
-        beginCommand(Command::SET_LAYER_SIDEBAND_STREAM, kSetLayerSidebandStreamLength);
-        writeHandle(stream);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSourceCropLength = 4;
-    void setLayerSourceCrop(const FRect& crop) {
-        beginCommand(Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
-        writeFRect(crop);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerTransformLength = 1;
-    void setLayerTransform(Transform transform) {
-        beginCommand(Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
-        writeSigned(static_cast<int32_t>(transform));
-        endCommand();
-    }
-
-    void setLayerVisibleRegion(const std::vector<Rect>& visible) {
-        bool doWrite = (visible.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? visible.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_VISIBLE_REGION, length);
-        // When there are too many rectangles in the visible region and
-        // doWrite is false, we write no rectangle at all which means the
-        // entire layer is visible.
-        if (doWrite) {
-            writeRegion(visible);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerZOrderLength = 1;
-    void setLayerZOrder(uint32_t z) {
-        beginCommand(Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
-        write(z);
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadata(const std::vector<PerFrameMetadata>& metadataVec) {
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA, metadataVec.size() * 2);
-        for (const auto& metadata : metadataVec) {
-            writeSigned(static_cast<int32_t>(metadata.key));
-            writeFloat(metadata.value);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorTransformLength = 16;
-    void setLayerColorTransform(const float* matrix) {
-        beginCommand(Command::SET_LAYER_COLOR_TRANSFORM, kSetLayerColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadataBlobs(const std::vector<PerFrameMetadataBlob>& metadata) {
-        // in units of uint32_t's
-        size_t commandLength = 0;
-
-        if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
-            LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
-            return;
-        }
-
-        // space for numElements
-        commandLength += 1;
-
-        for (auto metadataBlob : metadata) {
-            commandLength += 1;  // key of metadata blob
-            commandLength += 1;  // size information of metadata blob
-
-            // metadata content size
-            size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
-            commandLength += metadataSize;
-            commandLength +=
-                    (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
-        }
-
-        if (commandLength > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("dynamic metadata size is too large");
-            return;
-        }
-
-        // Blobs are written as:
-        // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
-        uint16_t length = static_cast<uint16_t>(commandLength);
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
-        write(static_cast<uint32_t>(metadata.size()));
-        for (auto metadataBlob : metadata) {
-            writeSigned(static_cast<int32_t>(metadataBlob.key));
-            write(static_cast<uint32_t>(metadataBlob.blob.size()));
-            writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerFloatColorLength = 4;
-    void setLayerFloatColor(FloatColor color) {
-        beginCommand(Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
-        writeFloatColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetClientTargetPropertyLength = 2;
-    void setClientTargetProperty(const ClientTargetProperty& clientTargetProperty) {
-        beginCommand(Command::SET_CLIENT_TARGET_PROPERTY, kSetClientTargetPropertyLength);
-        writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
-        writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
-        endCommand();
-    }
-
-    void setLayerGenericMetadata(const std::string& key, const bool mandatory,
-                                 const std::vector<uint8_t>& value) {
-        const size_t commandSize = 3 + sizeToElements(key.size()) + sizeToElements(value.size());
-        if (commandSize > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("Too much generic metadata (%zu elements)", commandSize);
-            return;
-        }
-
-        beginCommand(Command::SET_LAYER_GENERIC_METADATA, static_cast<uint16_t>(commandSize));
-        write(key.size());
-        writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
-        write(mandatory);
-        write(value.size());
-        writeBlob(value.size(), value.data());
-        endCommand();
+    std::vector<command::CommandResultPayload> getPendingCommandResults() {
+        return std::move(mCommandsResults);
     }
 
   protected:
-    template <typename T>
-    void beginCommand(T command, uint16_t length) {
-        beginCommandBase(static_cast<Command>(command), length);
+    command::Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
+        command::Buffer bufferCommand;
+        bufferCommand.slot = slot;
+        if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
+        if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
+        return bufferCommand;
     }
 
-    void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
-                                 int32_t dataspace, const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
-        size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
-
-        beginCommand(Command::SET_CLIENT_TARGET, length);
-        write(slot);
-        writeHandle(target, true);
-        writeFence(acquireFence);
-        writeSigned(dataspace);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // client target is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    void setLayerDataspaceInternal(int32_t dataspace) {
-        beginCommand(Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
-        writeSigned(dataspace);
-        endCommand();
-    }
-
-    void beginCommandBase(Command command, uint16_t length) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called before command 0x%x", command);
-        }
-
-        growData(1 + length);
-        write(static_cast<uint32_t>(command) | length);
-
-        mCommandEnd = mDataWritten + length;
-    }
-
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataWritten > mCommandEnd) {
-            LOG_FATAL("too much data written");
-            mDataWritten = mCommandEnd;
-        } else if (mDataWritten < mCommandEnd) {
-            LOG_FATAL("too little data written");
-            while (mDataWritten < mCommandEnd) {
-                write(0);
-            }
-        }
-
-        mCommandEnd = 0;
-    }
-
-    void write(uint32_t val) { mData[mDataWritten++] = val; }
-
-    void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void write64(uint64_t val) {
-        uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
-        uint32_t hi = static_cast<uint32_t>(val >> 32);
-        write(lo);
-        write(hi);
-    }
-
-    void writeRect(const Rect& rect) {
-        writeSigned(rect.left);
-        writeSigned(rect.top);
-        writeSigned(rect.right);
-        writeSigned(rect.bottom);
-    }
-
-    void writeRegion(const std::vector<Rect>& region) {
-        for (const auto& rect : region) {
-            writeRect(rect);
-        }
-    }
-
-    void writeFRect(const FRect& rect) {
-        writeFloat(rect.left);
-        writeFloat(rect.top);
-        writeFloat(rect.right);
-        writeFloat(rect.bottom);
-    }
-
-    void writeColor(const Color& color) {
-        write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
-    }
-
-    void writeFloatColor(const FloatColor& color) {
-        writeFloat(color.r);
-        writeFloat(color.g);
-        writeFloat(color.b);
-        writeFloat(color.a);
-    }
-
-    void writeBlob(uint32_t length, const unsigned char* blob) {
-        memcpy(&mData[mDataWritten], blob, length);
-        uint32_t numElements = length / 4;
-        mDataWritten += numElements;
-        mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
-    }
-
-    // ownership of handle is not transferred
-    void writeHandle(const native_handle_t* handle, bool useCache) {
-        if (!handle) {
-            writeSigned(
-                    static_cast<int32_t>((useCache) ? HandleIndex::CACHED : HandleIndex::EMPTY));
-            return;
-        }
-
-        mDataHandles.push_back(::android::dupToAidl(handle));
-        writeSigned(mDataHandles.size() - 1);
-    }
-
-    void writeHandle(const native_handle_t* handle) { writeHandle(handle, false); }
-
-    // ownership of fence is transferred
-    void writeFence(int fence) {
-        native_handle_t* handle = nullptr;
-        if (fence >= 0) {
-            handle = getTemporaryHandle(1, 0);
-            if (handle) {
-                handle->data[0] = fence;
-            } else {
-                ALOGW("failed to get temporary handle for fence %d", fence);
-                sync_wait(fence, -1);
-                close(fence);
-            }
-        }
-
-        writeHandle(handle);
-    }
-
-    native_handle_t* getTemporaryHandle(int numFds, int numInts) {
-        native_handle_t* handle = native_handle_create(numFds, numInts);
-        if (handle) {
-            mTemporaryHandles.push_back(handle);
-        }
-        return handle;
-    }
-
-    static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataWritten;
+    std::optional<command::DisplayCommand> mDisplayCommand;
+    std::optional<command::LayerCommand> mLayerCommand;
+    std::vector<command::CommandPayload> mCommands;
+    std::vector<command::CommandResultPayload> mCommandsResults;
 
   private:
-    void growData(uint32_t grow) {
-        uint32_t newWritten = mDataWritten + grow;
-        if (newWritten < mDataWritten) {
-            LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 ", growing by %" PRIu32,
-                             mDataWritten, grow);
-        }
+    // std::vector<native_handle_t*> mTemporaryHandles;
 
-        if (newWritten <= mDataMaxSize) {
-            return;
+    command::DisplayCommand& getDisplayCommand(int64_t display) {
+        if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+            if (mDisplayCommand.has_value()) mCommands.emplace_back(std::move(*mDisplayCommand));
+            mDisplayCommand.emplace();
+            mDisplayCommand->display = display;
+            return *mDisplayCommand;
         }
-
-        uint32_t newMaxSize = mDataMaxSize << 1;
-        if (newMaxSize < newWritten) {
-            newMaxSize = newWritten;
-        }
-
-        auto newData = std::make_unique<int32_t[]>(newMaxSize);
-        std::copy_n(mData.get(), mDataWritten, newData.get());
-        mDataMaxSize = newMaxSize;
-        mData = std::move(newData);
+        return *mDisplayCommand;
     }
 
-    uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
-
-    uint32_t mDataMaxSize;
-    // end offset of the current command
-    uint32_t mCommandEnd;
-
-    std::vector<NativeHandle> mDataHandles;
-    std::vector<native_handle_t*> mTemporaryHandles;
-
-    std::unique_ptr<CommandQueueType> mQueue;
+    command::LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
+        if (!mLayerCommand.has_value() || mLayerCommand->display != display ||
+            mLayerCommand->layer != layer) {
+            if (mLayerCommand.has_value()) mCommands.emplace_back(std::move(*mLayerCommand));
+            mLayerCommand.emplace();
+            mLayerCommand->display = display;
+            mLayerCommand->layer = layer;
+            return *mLayerCommand;
+        }
+        return *mLayerCommand;
+    }
 };
 
-// This class helps parse a command queue.  Note that all sizes/lengths are in
-// units of uint32_t's.
 class CommandReaderBase {
   public:
-    CommandReaderBase() : mDataMaxSize(0) { reset(); }
+    ~CommandReaderBase() { resetData(); }
 
-    bool setMQDescriptor(const DescriptorType& descriptor) {
-        mQueue = std::make_unique<CommandQueueType>(descriptor, false);
-        if (mQueue->isValid()) {
-            return true;
-        } else {
-            mQueue = nullptr;
-            return false;
+    // Parse and execute commands from the command queue.  The commands are
+    // actually return values from the server and will be saved in ReturnData.
+    void parse(const std::vector<command::CommandResultPayload>& results) {
+        resetData();
+
+        for (const auto& result : results) {
+            switch (result.getTag()) {
+                case command::CommandResultPayload::Tag::error:
+                    parseSetError(result.get<command::CommandResultPayload::Tag::error>());
+                    break;
+                case command::CommandResultPayload::Tag::changedCompositionType:
+                    parseSetChangedCompositionTypes(
+                            result.get<
+                                    command::CommandResultPayload::Tag::changedCompositionType>());
+                    break;
+                case command::CommandResultPayload::Tag::displayRequest:
+                    parseSetDisplayRequests(
+                            result.get<command::CommandResultPayload::Tag::displayRequest>());
+                    break;
+                case command::CommandResultPayload::Tag::presentFence:
+                    parseSetPresentFence(
+                            result.get<command::CommandResultPayload::Tag::presentFence>());
+                    break;
+                case command::CommandResultPayload::Tag::releaseFences:
+                    parseSetReleaseFences(
+                            result.get<command::CommandResultPayload::Tag::releaseFences>());
+                    break;
+                case command::CommandResultPayload::Tag::presentOrValidateResult:
+                    parseSetPresentOrValidateDisplayResult(
+                            result.get<
+                                    command::CommandResultPayload::Tag::presentOrValidateResult>());
+                    break;
+                case command::CommandResultPayload::Tag::clientTargetProperty:
+                    parseSetClientTargetProperty(
+                            result.get<command::CommandResultPayload::Tag::clientTargetProperty>());
+                    break;
+            }
         }
     }
 
-    bool readQueue(int32_t commandLength, std::vector<NativeHandle> commandHandles) {
-        if (!mQueue) {
+    std::vector<command::Error> takeErrors() { return std::move(mErrors); }
+
+    bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
+                    uint32_t* outNumLayerRequestMasks) const {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outNumChangedCompositionTypes = 0;
+            *outNumLayerRequestMasks = 0;
             return false;
         }
 
-        auto quantumCount = mQueue->getQuantumCount();
-        if (mDataMaxSize < quantumCount) {
-            mDataMaxSize = quantumCount;
-            mData = std::make_unique<int32_t[]>(mDataMaxSize);
+        const ReturnData& data = found->second;
+
+        *outNumChangedCompositionTypes = static_cast<uint32_t>(data.compositionTypes.size());
+        *outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
+
+        return !(data.compositionTypes.empty() && data.requestMasks.empty());
+    }
+
+    // Get and clear saved changed composition types.
+    void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
+                                     std::vector<Composition>* outTypes) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outTypes->clear();
+            return;
         }
 
-        if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
-            ALOGE("failed to read commands from message queue");
-            return false;
+        ReturnData& data = found->second;
+
+        *outLayers = std::move(data.changedLayers);
+        *outTypes = std::move(data.compositionTypes);
+    }
+
+    // Get and clear saved display requests.
+    void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask,
+                             std::vector<int64_t>* outLayers,
+                             std::vector<uint32_t>* outLayerRequestMasks) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outDisplayRequestMask = 0;
+            outLayers->clear();
+            outLayerRequestMasks->clear();
+            return;
         }
 
-        mDataSize = commandLength;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles = std::move(commandHandles);
-        return true;
+        ReturnData& data = found->second;
+
+        *outDisplayRequestMask = data.displayRequests;
+        *outLayers = std::move(data.requestedLayers);
+        *outLayerRequestMasks = std::move(data.requestMasks);
     }
 
-    void reset() {
-        mDataSize = 0;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles.clear();
-    }
-
-  protected:
-    template <typename T>
-    bool beginCommand(T* outCommand, uint16_t* outLength) {
-        return beginCommandBase(reinterpret_cast<Command*>(outCommand), outLength);
-    }
-
-    bool isEmpty() const { return (mDataRead >= mDataSize); }
-
-    bool beginCommandBase(Command* outCommand, uint16_t* outLength) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called for last command");
+    // Get and clear saved release fences.
+    void takeReleaseFences(int64_t display, std::vector<int64_t>* outLayers,
+                           std::vector<int>* outReleaseFences) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outReleaseFences->clear();
+            return;
         }
 
-        constexpr uint32_t opcode_mask = static_cast<uint32_t>(Command::OPCODE_MASK);
-        constexpr uint32_t length_mask = static_cast<uint32_t>(Command::LENGTH_MASK);
+        ReturnData& data = found->second;
 
-        uint32_t val = read();
-        *outCommand = static_cast<Command>(val & opcode_mask);
-        *outLength = static_cast<uint16_t>(val & length_mask);
+        *outLayers = std::move(data.releasedLayers);
+        *outReleaseFences = std::move(data.releaseFences);
+    }
 
-        if (mDataRead + *outLength > mDataSize) {
-            ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
-            // undo the read() above
-            mDataRead--;
-            return false;
+    // Get and clear saved present fence.
+    void takePresentFence(int64_t display, int* outPresentFence) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outPresentFence = -1;
+            return;
         }
 
-        mCommandEnd = mDataRead + *outLength;
+        ReturnData& data = found->second;
 
-        return true;
+        *outPresentFence = data.presentFence;
+        data.presentFence = -1;
     }
 
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataRead > mCommandEnd) {
-            LOG_FATAL("too much data read");
-            mDataRead = mCommandEnd;
-        } else if (mDataRead < mCommandEnd) {
-            LOG_FATAL("too little data read");
-            mDataRead = mCommandEnd;
+    // Get what stage succeeded during PresentOrValidate: Present or Validate
+    void takePresentOrValidateStage(int64_t display, uint32_t* state) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *state = static_cast<uint32_t>(-1);
+            return;
+        }
+        ReturnData& data = found->second;
+        *state = data.presentOrValidateState;
+    }
+
+    // Get the client target properties requested by hardware composer.
+    void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty) {
+        auto found = mReturnData.find(display);
+
+        // If not found, return the default values.
+        if (found == mReturnData.end()) {
+            outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888;
+            outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
+            return;
         }
 
-        mCommandBegin = mCommandEnd;
-        mCommandEnd = 0;
+        ReturnData& data = found->second;
+        *outClientTargetProperty = data.clientTargetProperty;
     }
 
-    uint32_t getCommandLoc() const { return mCommandBegin; }
-
-    uint32_t read() { return mData[mDataRead++]; }
-
-    int32_t readSigned() {
-        int32_t val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    float readFloat() {
-        float val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    uint64_t read64() {
-        uint32_t lo = read();
-        uint32_t hi = read();
-        return (static_cast<uint64_t>(hi) << 32) | lo;
-    }
-
-    Color readColor() {
-        uint32_t val = read();
-        return Color{
-                static_cast<int8_t>((val >> 0) & 0xff),
-                static_cast<int8_t>((val >> 8) & 0xff),
-                static_cast<int8_t>((val >> 16) & 0xff),
-                static_cast<int8_t>((val >> 24) & 0xff),
-        };
-    }
-
-    // ownership of handle is not transferred
-    const native_handle_t* readHandle(bool* outUseCache) {
-        const native_handle_t* handle = nullptr;
-
-        int32_t index = readSigned();
-        switch (index) {
-            case static_cast<int32_t>(HandleIndex::EMPTY):
-                *outUseCache = false;
-                break;
-            case static_cast<int32_t>(HandleIndex::CACHED):
-                *outUseCache = true;
-                break;
-            default:
-                if (static_cast<size_t>(index) < mDataHandles.size()) {
-                    handle = ::android::makeFromAidl(mDataHandles[index]);
-                } else {
-                    ALOGE("invalid handle index %zu", static_cast<size_t>(index));
-                }
-                *outUseCache = false;
-                break;
-        }
-
-        return handle;
-    }
-
-    const native_handle_t* readHandle() {
-        bool useCache;
-        return readHandle(&useCache);
-    }
-
-    // ownership of fence is transferred
-    int readFence() {
-        auto handle = readHandle();
-        if (!handle || handle->numFds == 0) {
-            return -1;
-        }
-
-        if (handle->numFds != 1) {
-            ALOGE("invalid fence handle with %d fds", handle->numFds);
-            return -1;
-        }
-
-        int fd = dup(handle->data[0]);
-        if (fd < 0) {
-            ALOGW("failed to dup fence %d", handle->data[0]);
-            sync_wait(handle->data[0], -1);
-            fd = -1;
-        }
-
-        return fd;
-    }
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataRead;
-
   private:
-    std::unique_ptr<CommandQueueType> mQueue;
-    uint32_t mDataMaxSize;
+    void resetData() {
+        mErrors.clear();
 
-    uint32_t mDataSize;
+        for (auto& data : mReturnData) {
+            if (data.second.presentFence >= 0) {
+                close(data.second.presentFence);
+            }
+            for (auto fence : data.second.releaseFences) {
+                if (fence >= 0) {
+                    close(fence);
+                }
+            }
+        }
 
-    // begin/end offsets of the current command
-    uint32_t mCommandBegin;
-    uint32_t mCommandEnd;
+        mReturnData.clear();
+    }
 
-    std::vector<NativeHandle> mDataHandles;
+    void parseSetError(const command::Error& error) { mErrors.emplace_back(error); }
+
+    void parseSetChangedCompositionTypes(
+            const command::ChangedCompositionTypes& changedCompositionTypes) {
+        auto& data = mReturnData[changedCompositionTypes.display];
+
+        data.changedLayers.reserve(changedCompositionTypes.layers.size());
+        data.compositionTypes.reserve(changedCompositionTypes.layers.size());
+        for (const auto& layer : changedCompositionTypes.layers) {
+            data.changedLayers.push_back(layer.layer);
+            data.compositionTypes.push_back(layer.composition);
+        }
+    }
+
+    void parseSetDisplayRequests(const command::DisplayRequest& displayRequest) {
+        auto& data = mReturnData[displayRequest.display];
+
+        data.displayRequests = displayRequest.mask;
+        data.requestedLayers.reserve(displayRequest.layerRequests.size());
+        data.requestMasks.reserve(displayRequest.layerRequests.size());
+        for (const auto& layerRequest : displayRequest.layerRequests) {
+            data.requestedLayers.push_back(layerRequest.layer);
+            data.requestMasks.push_back(layerRequest.mask);
+        }
+    }
+
+    void parseSetPresentFence(const command::PresentFence& presentFence) {
+        auto& data = mReturnData[presentFence.display];
+        if (data.presentFence >= 0) {
+            close(data.presentFence);
+        }
+        data.presentFence = dup(presentFence.fence.get());
+    }
+
+    void parseSetReleaseFences(const command::ReleaseFences& releaseFences) {
+        auto& data = mReturnData[releaseFences.display];
+        data.releasedLayers.reserve(releaseFences.layers.size());
+        data.releaseFences.reserve(releaseFences.layers.size());
+        for (const auto& layer : releaseFences.layers) {
+            data.releasedLayers.push_back(layer.layer);
+            data.releaseFences.push_back(dup(layer.fence.get()));
+        }
+    }
+
+    void parseSetPresentOrValidateDisplayResult(
+            const command::PresentOrValidate& presentOrValidate) {
+        auto& data = mReturnData[presentOrValidate.display];
+        data.presentOrValidateState =
+                presentOrValidate.result == command::PresentOrValidate::Result::Presented ? 1 : 0;
+    }
+
+    void parseSetClientTargetProperty(
+            const command::ClientTargetPropertyWithNits& clientTargetProperty) {
+        auto& data = mReturnData[clientTargetProperty.display];
+        data.clientTargetProperty.pixelFormat =
+                clientTargetProperty.clientTargetProperty.pixelFormat;
+        data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace;
+    }
+
+    struct ReturnData {
+        int32_t displayRequests = 0;
+
+        std::vector<int64_t> changedLayers;
+        std::vector<Composition> compositionTypes;
+
+        std::vector<int64_t> requestedLayers;
+        std::vector<uint32_t> requestMasks;
+
+        int presentFence = -1;
+
+        std::vector<int64_t> releasedLayers;
+        std::vector<int> releaseFences;
+
+        uint32_t presentOrValidateState;
+
+        ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
+                                                  Dataspace::UNKNOWN};
+    };
+
+    std::vector<command::Error> mErrors;
+    std::unordered_map<int64_t, ReturnData> mReturnData;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
index c892863..7004955 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
@@ -17,25 +17,22 @@
 #pragma once
 
 #include <limits>
+#include "aidl/android/hardware/graphics/common/BlendMode.h"
 #include "aidl/android/hardware/graphics/common/FRect.h"
 #include "aidl/android/hardware/graphics/common/Rect.h"
-#include "aidl/android/hardware/graphics/composer3/BlendMode.h"
 #include "aidl/android/hardware/graphics/composer3/Capability.h"
 #include "aidl/android/hardware/graphics/composer3/ClientTargetProperty.h"
 #include "aidl/android/hardware/graphics/composer3/Color.h"
-#include "aidl/android/hardware/graphics/composer3/Command.h"
 #include "aidl/android/hardware/graphics/composer3/Composition.h"
 #include "aidl/android/hardware/graphics/composer3/ContentType.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayCapability.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h"
-#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
 #include "aidl/android/hardware/graphics/composer3/FloatColor.h"
 #include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h"
 #include "aidl/android/hardware/graphics/composer3/HandleIndex.h"
 #include "aidl/android/hardware/graphics/composer3/IComposer.h"
 #include "aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.h"
-#include "aidl/android/hardware/graphics/composer3/LayerRequest.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.h"
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index fae7592..6e2f1d4 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -25,6 +25,7 @@
     name: "android.hardware.health",
     vendor_available: true,
     recovery_available: true,
+    host_supported: true,
     srcs: ["android/hardware/health/*.aidl"],
     stability: "vintf",
     backend: {
@@ -48,6 +49,7 @@
     name: "android.hardware.health-translate-ndk",
     vendor_available: true,
     recovery_available: true,
+    host_supported: true,
     srcs: ["android/hardware/health/translate-ndk.cpp"],
     shared_libs: [
         "libbinder_ndk",
@@ -61,6 +63,9 @@
         "android.hardware.health@2.0",
         "android.hardware.health@2.1",
     ],
+    defaults: [
+        "libbinder_ndk_host_user",
+    ],
 }
 
 java_library {
diff --git a/health/aidl/README.md b/health/aidl/README.md
new file mode 100644
index 0000000..a64fe93
--- /dev/null
+++ b/health/aidl/README.md
@@ -0,0 +1,320 @@
+# Health AIDL HAL
+
+## Determine whether the example service implementation is sufficient {#determine}
+
+You need a custom implementation if any of the following is true:
+
+* You are migrating from a custom
+  [health 2.1 HIDL HAL implementation](../2.1/README.md).
+* System properties `ro.charger.enable_suspend` and/or `ro.charger.no_ui`
+  are set to a `true` value. See [below](#charger-sysprops).
+* The device supports offline charging mode, and the `service`
+  declaration with `class charger` in `init.rc` is different from the one
+  provided by the example implementation. See [below](#charger-init-rc).
+
+If the example HAL service is sufficient, [install it](#use-example). Otherwise,
+[implement a custom HAL service](#use-custom).
+
+### System properties for charger {#charger-sysprops}
+
+The health AIDL HAL service also provides functionalities of `charger`. As a
+result, the system charger at `/system/bin/charger` is deprecated.
+
+However, the health AIDL HAL service is not allowed to read `ro.charger.*`
+system properties. These properties include:
+* `ro.charger.enable_suspend`. If set, you need a custom health AIDL HAL
+  service. See [below](#charger-enable-suspend).
+* `ro.charger.no_ui`. If set, you need a custom health AIDL HAL service.
+  See [below](#charger-no-ui).
+* `ro.charger.draw_split_screen`. The system property is deprecated.
+* `ro.charger.draw_split_offset`. The system property is deprecated.
+* `ro.charger.disable_init_blank`. The system property is deprecated.
+
+If you need to set any of the deprecated system properties, contact
+[OWNERS](OWNERS).
+
+### Default `service` declaration for charger in `init.rc` {#charger-init-rc}
+
+See
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
+
+Check the `service` declaration in your device-specific `init.rc` file that
+has `class charger`. Most likely, the declaration looks something like this
+(Below is an excerpt from Pixel 3):
+
+```text
+service vendor.charger /system/bin/charger
+    class charger
+    seclabel u:r:charger:s0
+    user system
+    group system wakelock input
+    capabilities SYS_BOOT
+    file /dev/kmsg w
+    file /sys/fs/pstore/console-ramoops-0 r
+    file /sys/fs/pstore/console-ramoops r
+    file /proc/last_kmsg r
+```
+
+Compare each line against the one provided by the example health AIDL HAL
+service in
+[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.
+* 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`.
+* If your service has a different `user` (not `system`), you need a custom
+  health AIDL service.
+* If your service belongs to additional `group`s beside
+  `system wakelock input`, you need a custom health AIDL service.
+* If your service requires additional capabilities beside `SYS_BOOT`,
+  you need a custom health AIDL service.
+* If your service requires additional `file`s to be opened prior to execution,
+  you need a custom health AIDL service.
+
+## Using the example health AIDL HAL service {#use-example}
+
+If you [determined](#determine) that the example health AIDL HAL service works
+for your device, install it with
+
+```mk
+PRODUCT_PACKAGES += \
+    android.hardware.health-service.example \
+    android.hardware.health-service.example_recovery \
+```
+
+Then, delete any existing `service` with `class charger` in your device-specific
+`init.rc` files, because
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
+already contains an entry for charger.
+
+If your device supports charger mode and it has custom charger resources,
+[move charger resources to `/vendor`](#charger-res)
+
+## Implementing a custom health AIDL HAL service {#use-custom}
+
+### Override the `Health` class {#health-impl}
+
+See [`Health.h`](default/include/health-impl/Health.h) for its class
+declaration. Inherit the class to customize for your device.
+
+```c++
+namespace aidl::android::hardware::health {
+class HealthImpl : public Health {
+    // ...
+};
+} // namespace aidl::android::hardware::health
+int main(int, char**) {
+    // ...
+    auto binder = ndk::SharedRefBase::make<aidl::android::hardware::health::HealthImpl>(
+            "default", std::move(config));
+    // ...
+}
+```
+
+* The logic to modify `healthd_config`, traditionally in `healthd_board_init()`
+  should be called before passing the `healthd_config` struct to your
+  `HealthImpl` class in [`main()`](#main).
+
+* The following functions are similar to the ones in the health 2.1 HIDL HAL:
+
+| AIDL implementation                 | HIDL implementation         |
+|-------------------------------------|-----------------------------|
+| `Health::getChargeCounterUah`       | `Health::getChargeCounter`  |
+| `Health::getCurrentNowMicroamps`    | `Health::getCurrentNow`     |
+| `Health::getCurrentAverageMicroamps`| `Health::getCurrentAverage` |
+| `Health::getCapacity`               | `Health::getCapacity`       |
+| `Health::getChargeStatus`           | `Health::getChargeStatus`   |
+| `Health::getEnergyCounterNwh`       | `Health::getEnergyCounter`  |
+| `Health::getDiskStats`              | `Health::getDiskStats`      |
+| `Health::getStorageInfo`            | `Health::getStorageInfo`    |
+| `Health::BinderEvent`               | `BinderHealth::BinderEvent` |
+| `Health::dump`                      | `Health::debug`             |
+| `Health::ShouldKeepScreenOn`        | `Health::shouldKeepScreenOn`|
+| `Health::UpdateHealthInfo`          | `Health::UpdateHealthInfo`  |
+
+### Implement `main()` {#main}
+
+See the [`main.cpp`](default/main.cpp) for the example health AIDL service for
+an example.
+
+If you need to modify `healthd_config`, do it before passing it to the
+constructor of `HealthImpl` (or `Health` if you did not implement a subclass
+of it).
+
+```c++
+int main(int argc, char** argv) {
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    healthd_board_init(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+    // ...
+}
+```
+
+If your device does not support off-line charging mode, or does not have a UI
+for charger (`ro.charger.no_ui=true`), skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+### Build system changes
+
+Install both the platform and recovery variant of the service. For example:
+
+```mk
+PRODUCT_PACKAGES += \
+    android.hardware.health-service.cuttlefish \
+    android.hardware.health-service.cuttlefish_recovery \
+```
+
+### SELinux rules
+
+Add device specific permissions to the domain where the health HAL
+process is executed, especially if a device-specific `libhealthd` is used
+and/or device-specific storage related APIs are implemented.
+
+Example (assuming that your health AIDL service runs in domain
+`hal_health_tuna`:
+
+```text
+type hal_health_tuna, domain;
+hal_server_domain(hal_health_tuna, hal_health)
+type hal_health_tuna_exec, exec_type, vendor_file_type, file_type;
+
+# allow hal_health_tuna ...;
+```
+
+If you did not define a separate domain, the domain is likely
+`hal_health_default`. The device-specific rules for it is likely at
+`device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te`.
+In this case, the aforementioned SELinux rules and types has already been
+defined. You only need to add device-specific permissions.
+
+```text
+# allow hal_health_default ...;
+```
+
+### Implementing charger {#charger}
+
+#### Move charger resources to `/vendor`
+
+Ensure that charger resources are installed to `/vendor`, not `/product`.
+
+`animation.txt` must be moved to the following location:
+
+```text
+/vendor/etc/res/values/charger/animation.txt
+```
+
+Charger resources in `/system` is not read by the health HAL service in
+`/vendor`. Specifically, resources should be installed to the following
+location:
+
+```
+/vendor/etc/res/images/charger/*.png
+```
+
+If resources are not found in these locations, the health HAL service falls
+back to the following locations:
+
+```
+/vendor/etc/res/images/charger/default/*.png
+```
+
+You can use the default resources by installing the default module:
+
+```makefile
+PRODUCT_PACKAGES += charger_res_images_vendor
+```
+
+#### Modify `init.rc` for charger
+
+It is recommended that you move the existing `service` entry with
+`class charger` to the `init.rc` file in your custom health service.
+
+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
+    class charger
+    seclabel u:r:charger_vendor:s0
+    # ...
+```
+
+#### No charger mode {#no-charger}
+
+If your device does not support off-line charging mode, skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+```c++
+int main(int, char**) {
+    // ...
+    // Skip checking if arguments contain "--charger"
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+    return hal_health_loop->StartLoop();
+}
+```
+
+You may optionally delete the `service` entry with `class charger` in the
+`init.rc` file.
+
+#### No charger UI {#charger-no-ui}
+
+If your device does not have a UI for charger (`ro.charger.no_ui=true`), skip
+the invocation of `ChargerModeMain()` in `main()`.
+
+You may want to keep the `KernelLogger` so that charger still logs battery
+information to the kernel logs.
+
+```c++
+int main(int argc, char** argv) {
+    // ...
+    if (argc >= 2 && argv[1] == "--charger"sv) {
+        android::base::InitLogging(argv, &android::base::KernelLogger);
+        // fallthrough to HalHealthLoop::StartLoop()
+    }
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+    return hal_health_loop->StartLoop();
+}
+```
+
+#### Enable suspend {#charger-enable-suspend}
+
+If your device has `ro.charger.enable_suspend=true`, implement a new class,
+`ChargerCallbackImpl`, that inherits from
+[`ChargerCallback`](default/include/health-impl/ChargerUtils.h). Then
+override the `ChargerEnableSuspend` function to return `true`. Then pass an
+instance of `ChargerCallbackImpl` to `ChargerModeMain()` instead.
+
+```c++
+namespace aidl::android::hardware::health {
+class ChargerCallbackImpl : public ChargerCallback {
+    bool ChargerEnableSuspend() override { return true; }
+};
+} // namespace aidl::android::hardware::health
+int main(int argc, char** argv) {
+    // ...
+    if (argc >= 2 && argv[1] == "--charger"sv) {
+        android::base::InitLogging(argv, &android::base::KernelLogger);
+#if !CHARGER_FORCE_NO_UI
+        return ChargerModeMain(binder,
+                std::make_shared<aidl::android::hardware::health::ChargerCallbackImpl>(binder));
+#endif
+    }
+    // ...
+}
+```
+
+#### SELinux rules for charger
+
+If your health AIDL service runs in a domain other than `hal_health_default`,
+add `charger_type` to it so the health HAL service can have charger-specific
+permissions. Example (assuming that your health AIDL service runs in domain
+`hal_health_tuna`:
+
+```text
+domain_trans(init, hal_health_tuna_exec, charger_vendor)
+```
diff --git a/health/aidl/android/hardware/health/Translate.java b/health/aidl/android/hardware/health/Translate.java
index c8ace1c..4f840b8 100644
--- a/health/aidl/android/hardware/health/Translate.java
+++ b/health/aidl/android/hardware/health/Translate.java
@@ -44,25 +44,37 @@
         return out;
     }
 
+    private static void h2aTranslateInternal(
+            android.hardware.health.HealthInfo out, android.hardware.health.V1_0.HealthInfo in) {
+        out.chargerAcOnline = in.chargerAcOnline;
+        out.chargerUsbOnline = in.chargerUsbOnline;
+        out.chargerWirelessOnline = in.chargerWirelessOnline;
+        out.maxChargingCurrentMicroamps = in.maxChargingCurrent;
+        out.maxChargingVoltageMicrovolts = in.maxChargingVoltage;
+        out.batteryStatus = in.batteryStatus;
+        out.batteryHealth = in.batteryHealth;
+        out.batteryPresent = in.batteryPresent;
+        out.batteryLevel = in.batteryLevel;
+        out.batteryVoltageMillivolts = in.batteryVoltage;
+        out.batteryTemperatureTenthsCelsius = in.batteryTemperature;
+        out.batteryCurrentMicroamps = in.batteryCurrent;
+        out.batteryCycleCount = in.batteryCycleCount;
+        out.batteryFullChargeUah = in.batteryFullCharge;
+        out.batteryChargeCounterUah = in.batteryChargeCounter;
+        out.batteryTechnology = in.batteryTechnology;
+    }
+
+    public static android.hardware.health.HealthInfo h2aTranslate(
+            android.hardware.health.V1_0.HealthInfo in) {
+        android.hardware.health.HealthInfo out = new android.hardware.health.HealthInfo();
+        h2aTranslateInternal(out, in);
+        return out;
+    }
+
     static public android.hardware.health.HealthInfo h2aTranslate(
             android.hardware.health.V2_1.HealthInfo in) {
         android.hardware.health.HealthInfo out = new android.hardware.health.HealthInfo();
-        out.chargerAcOnline = in.legacy.legacy.chargerAcOnline;
-        out.chargerUsbOnline = in.legacy.legacy.chargerUsbOnline;
-        out.chargerWirelessOnline = in.legacy.legacy.chargerWirelessOnline;
-        out.maxChargingCurrentMicroamps = in.legacy.legacy.maxChargingCurrent;
-        out.maxChargingVoltageMicrovolts = in.legacy.legacy.maxChargingVoltage;
-        out.batteryStatus = in.legacy.legacy.batteryStatus;
-        out.batteryHealth = in.legacy.legacy.batteryHealth;
-        out.batteryPresent = in.legacy.legacy.batteryPresent;
-        out.batteryLevel = in.legacy.legacy.batteryLevel;
-        out.batteryVoltageMillivolts = in.legacy.legacy.batteryVoltage;
-        out.batteryTemperatureTenthsCelsius = in.legacy.legacy.batteryTemperature;
-        out.batteryCurrentMicroamps = in.legacy.legacy.batteryCurrent;
-        out.batteryCycleCount = in.legacy.legacy.batteryCycleCount;
-        out.batteryFullChargeUah = in.legacy.legacy.batteryFullCharge;
-        out.batteryChargeCounterUah = in.legacy.legacy.batteryChargeCounter;
-        out.batteryTechnology = in.legacy.legacy.batteryTechnology;
+        h2aTranslateInternal(out, in.legacy.legacy);
         out.batteryCurrentAverageMicroamps = in.legacy.batteryCurrentAverage;
         out.diskStats = new android.hardware.health.DiskStats[in.legacy.diskStats.size()];
         for (int i = 0; i < in.legacy.diskStats.size(); i++) {
diff --git a/health/aidl/android/hardware/health/translate-ndk.cpp b/health/aidl/android/hardware/health/translate-ndk.cpp
index 7fe6ced..78880cc 100644
--- a/health/aidl/android/hardware/health/translate-ndk.cpp
+++ b/health/aidl/android/hardware/health/translate-ndk.cpp
@@ -106,36 +106,41 @@
 }
 
 __attribute__((warn_unused_result)) bool translate(
+        const ::android::hardware::health::V2_0::HealthInfo& in,
+        aidl::android::hardware::health::HealthInfo* out) {
+    out->chargerAcOnline = static_cast<bool>(in.legacy.chargerAcOnline);
+    out->chargerUsbOnline = static_cast<bool>(in.legacy.chargerUsbOnline);
+    out->chargerWirelessOnline = static_cast<bool>(in.legacy.chargerWirelessOnline);
+    out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.maxChargingCurrent);
+    out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.maxChargingVoltage);
+    out->batteryStatus =
+            static_cast<aidl::android::hardware::health::BatteryStatus>(in.legacy.batteryStatus);
+    out->batteryHealth =
+            static_cast<aidl::android::hardware::health::BatteryHealth>(in.legacy.batteryHealth);
+    out->batteryPresent = static_cast<bool>(in.legacy.batteryPresent);
+    out->batteryLevel = static_cast<int32_t>(in.legacy.batteryLevel);
+    out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.batteryVoltage);
+    out->batteryTemperatureTenthsCelsius = static_cast<int32_t>(in.legacy.batteryTemperature);
+    out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.batteryCurrent);
+    out->batteryCycleCount = static_cast<int32_t>(in.legacy.batteryCycleCount);
+    out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.batteryFullCharge);
+    out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.batteryChargeCounter);
+    out->batteryTechnology = in.legacy.batteryTechnology;
+    out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.batteryCurrentAverage);
+    out->diskStats.clear();
+    out->diskStats.resize(in.diskStats.size());
+    for (size_t i = 0; i < in.diskStats.size(); ++i)
+        if (!translate(in.diskStats[i], &out->diskStats[i])) return false;
+    out->storageInfos.clear();
+    out->storageInfos.resize(in.storageInfos.size());
+    for (size_t i = 0; i < in.storageInfos.size(); ++i)
+        if (!translate(in.storageInfos[i], &out->storageInfos[i])) return false;
+    return true;
+}
+__attribute__((warn_unused_result)) bool translate(
         const ::android::hardware::health::V2_1::HealthInfo& in,
         aidl::android::hardware::health::HealthInfo* out) {
-    out->chargerAcOnline = static_cast<bool>(in.legacy.legacy.chargerAcOnline);
-    out->chargerUsbOnline = static_cast<bool>(in.legacy.legacy.chargerUsbOnline);
-    out->chargerWirelessOnline = static_cast<bool>(in.legacy.legacy.chargerWirelessOnline);
-    out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.maxChargingCurrent);
-    out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.legacy.maxChargingVoltage);
-    out->batteryStatus = static_cast<aidl::android::hardware::health::BatteryStatus>(
-            in.legacy.legacy.batteryStatus);
-    out->batteryHealth = static_cast<aidl::android::hardware::health::BatteryHealth>(
-            in.legacy.legacy.batteryHealth);
-    out->batteryPresent = static_cast<bool>(in.legacy.legacy.batteryPresent);
-    out->batteryLevel = static_cast<int32_t>(in.legacy.legacy.batteryLevel);
-    out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.legacy.batteryVoltage);
-    out->batteryTemperatureTenthsCelsius =
-            static_cast<int32_t>(in.legacy.legacy.batteryTemperature);
-    out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.batteryCurrent);
-    out->batteryCycleCount = static_cast<int32_t>(in.legacy.legacy.batteryCycleCount);
-    out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.legacy.batteryFullCharge);
-    out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.legacy.batteryChargeCounter);
-    out->batteryTechnology = in.legacy.legacy.batteryTechnology;
-    out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.legacy.batteryCurrentAverage);
-    out->diskStats.clear();
-    out->diskStats.resize(in.legacy.diskStats.size());
-    for (size_t i = 0; i < in.legacy.diskStats.size(); ++i)
-        if (!translate(in.legacy.diskStats[i], &out->diskStats[i])) return false;
-    out->storageInfos.clear();
-    out->storageInfos.resize(in.legacy.storageInfos.size());
-    for (size_t i = 0; i < in.legacy.storageInfos.size(); ++i)
-        if (!translate(in.legacy.storageInfos[i], &out->storageInfos[i])) return false;
+    if (!translate(in.legacy, out)) return false;
     out->batteryCapacityLevel = static_cast<aidl::android::hardware::health::BatteryCapacityLevel>(
             in.batteryCapacityLevel);
     out->batteryChargeTimeToFullNowSeconds =
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 7e635d4..8aa7638 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -23,8 +23,6 @@
 
 cc_defaults {
     name: "libhealth_aidl_common_defaults",
-    recovery_available: true,
-    vendor: true,
     shared_libs: [
         "libbase",
         "libbinder_ndk",
@@ -45,6 +43,52 @@
     ],
 }
 
+// Dependency to libhealthd_charger_ui. No UI in recovery.
+cc_defaults {
+    name: "libhealth_aidl_charger_defaults",
+    shared_libs: [
+        // common
+        "android.hardware.health-V1-ndk",
+        "libbase",
+        "libcutils",
+        "liblog",
+        "libutils",
+
+        // charger UI only
+        "libpng",
+    ],
+
+    static_libs: [
+        // common
+        "libbatterymonitor",
+        "libhealthloop",
+
+        // charger UI only
+        "libhealthd_draw",
+        "libhealthd_charger_ui",
+        "libminui",
+        "libsuspend",
+    ],
+
+    target: {
+        recovery: {
+            // No UI and libsuspend for recovery charger.
+            cflags: [
+                "-DCHARGER_FORCE_NO_UI=1",
+            ],
+            exclude_shared_libs: [
+                "libpng",
+            ],
+            exclude_static_libs: [
+                "libhealthd_draw",
+                "libhealthd_charger_ui",
+                "libminui",
+                "libsuspend",
+            ],
+        },
+    },
+}
+
 // AIDL version of libhealth2impl.
 // A helper library for health HAL implementation.
 // HAL implementations can link to this library and extend the Health class.
@@ -52,35 +96,58 @@
     name: "libhealth_aidl_impl",
     defaults: [
         "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
     ],
+    vendor: true,
+    recovery_available: true,
     export_include_dirs: ["include"],
     export_static_lib_headers: [
         "libbatterymonitor",
     ],
     srcs: [
+        "ChargerUtils.cpp",
         "health-convert.cpp",
         "HalHealthLoop.cpp",
         "Health.cpp",
         "LinkedCallback.cpp",
     ],
-    visibility: [
-        ":__subpackages__",
-        "//hardware/interfaces/tests/extension/health:__subpackages__",
-    ],
+    target: {
+        recovery: {
+            exclude_srcs: [
+                "ChargerUtils.cpp",
+            ],
+        },
+    },
 }
 
 // AIDL version of android.hardware.health@2.1-service.
 // Default binder service of the health HAL.
-cc_binary {
-    name: "android.hardware.health-service.example",
+cc_defaults {
+    name: "android.hardware.health-service.example-defaults",
     relative_install_path: "hw",
-    init_rc: ["android.hardware.health-service.example.rc"],
     vintf_fragments: ["android.hardware.health-service.example.xml"],
     defaults: [
         "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
     ],
     static_libs: [
         "libhealth_aidl_impl",
     ],
     srcs: ["main.cpp"],
 }
+
+cc_binary {
+    name: "android.hardware.health-service.example",
+    vendor: true,
+    defaults: ["android.hardware.health-service.example-defaults"],
+    init_rc: ["android.hardware.health-service.example.rc"],
+    overrides: ["charger"],
+}
+
+cc_binary {
+    name: "android.hardware.health-service.example_recovery",
+    recovery: true,
+    defaults: ["android.hardware.health-service.example-defaults"],
+    init_rc: ["android.hardware.health-service.example_recovery.rc"],
+    overrides: ["charger.recovery"],
+}
diff --git a/health/aidl/default/ChargerUtils.cpp b/health/aidl/default/ChargerUtils.cpp
new file mode 100644
index 0000000..f8e208b
--- /dev/null
+++ b/health/aidl/default/ChargerUtils.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <health-impl/ChargerUtils.h>
+
+namespace aidl::android::hardware::health::charger {
+
+std::optional<bool> ChargerCallback::ChargerShouldKeepScreenOn() {
+    return service_->ShouldKeepScreenOn();
+}
+
+bool ChargerCallback::ChargerIsOnline() {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        // Assume no charger
+        return false;
+    }
+    return hal_health_loop_sp->charger_online();
+}
+
+void ChargerCallback::ChargerInitConfig(healthd_config* config) {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        return;
+    }
+    return service_->OnInit(hal_health_loop_sp.get(), config);
+}
+
+int ChargerCallback::ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
+    auto hal_health_loop_sp = hal_health_loop_.lock();
+    if (hal_health_loop_sp == nullptr) {
+        return -1;
+    }
+    return hal_health_loop_sp->RegisterEvent(fd, func, wakeup);
+}
+
+void ChargerCallback::set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop) {
+    hal_health_loop_ = std::move(hal_health_loop);
+}
+
+// Implements HalHealthLoopCallback for AIDL charger
+// Adapter of (Charger, Health) ->  HalHealthLoopCallback
+class LoopCallback : public HalHealthLoopCallback {
+  public:
+    LoopCallback(const std::shared_ptr<Health>& service, ChargerCallback* charger_callback)
+        : service_(service), charger_(std::make_unique<::android::Charger>(charger_callback)) {}
+
+    void OnHeartbeat() override {
+        service_->OnHeartbeat();
+        charger_->OnHeartbeat();
+    }
+    // Return the minimum timeout. Negative values are treated as no values.
+    int OnPrepareToWait() override {
+        int timeout1 = service_->OnPrepareToWait();
+        int timeout2 = charger_->OnPrepareToWait();
+
+        if (timeout1 < 0) return timeout2;
+        if (timeout2 < 0) return timeout1;
+        return std::min(timeout1, timeout2);
+    }
+
+    void OnInit(HalHealthLoop*, struct healthd_config* config) override {
+        // Charger::OnInit calls ChargerInitConfig, which calls into the real Health::OnInit.
+        charger_->OnInit(config);
+    }
+
+    void OnHealthInfoChanged(const HealthInfo& health_info) override {
+        charger_->OnHealthInfoChanged(::android::ChargerHealthInfo{
+                .battery_level = health_info.batteryLevel,
+                .battery_status = health_info.batteryStatus,
+        });
+        service_->OnHealthInfoChanged(health_info);
+    }
+
+  private:
+    std::shared_ptr<Health> service_;
+    std::unique_ptr<::android::Charger> charger_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+                    const std::shared_ptr<ChargerCallback>& charger_callback) {
+    LOG(INFO) << "Starting charger mode.";
+    //   parent stack ==========================================
+    //   current stack                                         ||
+    //    ||                                                   ||
+    //    V                                                    V
+    // hal_health_loop => loop_callback => charger --(raw)--> charger_callback
+    //    ^----------------(weak)---------------------------------'
+    auto loop_callback = std::make_shared<LoopCallback>(binder, charger_callback.get());
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, std::move(loop_callback));
+    charger_callback->set_hal_health_loop(hal_health_loop);
+    return hal_health_loop->StartLoop();
+}
+
+}  // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 812e64a..e1d1982 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -60,6 +60,8 @@
     battery_monitor_.init(healthd_config_.get());
 }
 
+Health::~Health() {}
+
 //
 // Getters.
 //
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index b393c58..4258890 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -4,3 +4,14 @@
     group system
     capabilities WAKE_ALARM BLOCK_SUSPEND
     file /dev/kmsg w
+
+service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
+    class charger
+    seclabel u:r:charger_vendor:s0
+    user system
+    group system wakelock input
+    capabilities SYS_BOOT
+    file /dev/kmsg w
+    file /sys/fs/pstore/console-ramoops-0 r
+    file /sys/fs/pstore/console-ramoops r
+    file /proc/last_kmsg r
diff --git a/health/aidl/default/android.hardware.health-service.example_recovery.rc b/health/aidl/default/android.hardware.health-service.example_recovery.rc
new file mode 100644
index 0000000..0001170
--- /dev/null
+++ b/health/aidl/default/android.hardware.health-service.example_recovery.rc
@@ -0,0 +1,7 @@
+service vendor.health-default /system/bin/hw/android.hardware.health-service.example_recovery
+    class hal
+    seclabel u:r:hal_health_default:s0
+    user system
+    group system
+    capabilities WAKE_ALARM BLOCK_SUSPEND
+    file /dev/kmsg w
diff --git a/health/aidl/default/include/health-impl/ChargerUtils.h b/health/aidl/default/include/health-impl/ChargerUtils.h
new file mode 100644
index 0000000..8f94181
--- /dev/null
+++ b/health/aidl/default/include/health-impl/ChargerUtils.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <optional>
+#include <type_traits>
+
+#include <android/binder_auto_utils.h>
+#include <charger/healthd_mode_charger.h>
+#include <health-impl/Health.h>
+
+#pragma once
+
+namespace aidl::android::hardware::health::charger {
+
+// Implements ChargerHalHealthLoopInterface for AIDL charger
+// Adapter of (Health, HalHealthLoop) -> ChargerHalHealthLoopInterface
+class ChargerCallback : public ::android::ChargerConfigurationInterface {
+  public:
+    ChargerCallback(const std::shared_ptr<Health>& service) : service_(service) {}
+    std::optional<bool> ChargerShouldKeepScreenOn() override;
+    bool ChargerIsOnline() override;
+    void ChargerInitConfig(healthd_config* config) override;
+    int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) override;
+
+    // Override to return true to replace `ro.charger.enable_suspend=true`
+    bool ChargerEnableSuspend() override { return false; }
+
+    void set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop);
+
+  private:
+    std::shared_ptr<Health> service_;
+    std::weak_ptr<HalHealthLoop> hal_health_loop_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+                    const std::shared_ptr<ChargerCallback>& charger_callback);
+
+}  // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index e49f44c..6bd4946 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -43,6 +43,7 @@
     // A subclass may modify |config| before passing it to the parent constructor.
     // See implementation of Health for code samples.
     Health(std::string_view instance_name, std::unique_ptr<struct healthd_config>&& config);
+    virtual ~Health();
 
     ndk::ScopedAStatus registerCallback(
             const std::shared_ptr<IHealthInfoCallback>& callback) override;
diff --git a/health/aidl/default/main.cpp b/health/aidl/default/main.cpp
index 014ae34..03b2ecb 100644
--- a/health/aidl/default/main.cpp
+++ b/health/aidl/default/main.cpp
@@ -19,17 +19,48 @@
 #include <health-impl/Health.h>
 #include <health/utils.h>
 
+#ifndef CHARGER_FORCE_NO_UI
+#define CHARGER_FORCE_NO_UI 0
+#endif
+
+#if !CHARGER_FORCE_NO_UI
+#include <health-impl/ChargerUtils.h>
+#endif
+
 using aidl::android::hardware::health::HalHealthLoop;
 using aidl::android::hardware::health::Health;
 
-static constexpr const char* gInstanceName = "default";
+#if !CHARGER_FORCE_NO_UI
+using aidl::android::hardware::health::charger::ChargerCallback;
+using aidl::android::hardware::health::charger::ChargerModeMain;
+#endif
 
-int main() {
-    // TODO(b/203246116): handle charger
+static constexpr const char* gInstanceName = "default";
+static constexpr std::string_view gChargerArg{"--charger"};
+
+int main(int argc, char** argv) {
+#ifdef __ANDROID_RECOVERY__
+    android::base::InitLogging(argv, android::base::KernelLogger);
+#endif
+
     // make a default health service
     auto config = std::make_unique<healthd_config>();
     ::android::hardware::health::InitHealthdConfig(config.get());
     auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
+
+    if (argc >= 2 && argv[1] == gChargerArg) {
+#if !CHARGER_FORCE_NO_UI
+        // If charger shouldn't have UI for your device, simply drop the line below
+        // for your service implementation. This corresponds to
+        // ro.charger.no_ui=true
+        return ChargerModeMain(binder, std::make_shared<ChargerCallback>(binder));
+#endif
+
+        LOG(INFO) << "Starting charger mode without UI.";
+    } else {
+        LOG(INFO) << "Starting health HAL.";
+    }
+
     auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
     return hal_health_loop->StartLoop();
 }
diff --git a/health/aidl/include/android/hardware/health/translate-ndk.h b/health/aidl/include/android/hardware/health/translate-ndk.h
index 2f8fe04..91add42 100644
--- a/health/aidl/include/android/hardware/health/translate-ndk.h
+++ b/health/aidl/include/android/hardware/health/translate-ndk.h
@@ -33,6 +33,9 @@
         const ::android::hardware::health::V2_0::DiskStats& in,
         aidl::android::hardware::health::DiskStats* out);
 __attribute__((warn_unused_result)) bool translate(
+        const ::android::hardware::health::V2_0::HealthInfo& in,
+        aidl::android::hardware::health::HealthInfo* out);
+__attribute__((warn_unused_result)) bool translate(
         const ::android::hardware::health::V2_1::HealthInfo& in,
         aidl::android::hardware::health::HealthInfo* out);
 
diff --git a/health/storage/aidl/default/main.cpp b/health/storage/aidl/default/main.cpp
index 186b64c..74e266f 100644
--- a/health/storage/aidl/default/main.cpp
+++ b/health/storage/aidl/default/main.cpp
@@ -24,14 +24,19 @@
 using std::string_literals::operator""s;
 
 int main() {
+    LOG(INFO) << "Health storage AIDL HAL starting...";
     ABinderProcess_setThreadPoolMaxThreadCount(0);
 
     // make a default storage service
     auto storage = ndk::SharedRefBase::make<Storage>();
     const std::string name = Storage::descriptor + "/default"s;
+    LOG(INFO) << "Health storage AIDL HAL registering...";
     CHECK_EQ(STATUS_OK,
              AServiceManager_registerLazyService(storage->asBinder().get(), name.c_str()));
 
+    LOG(INFO) << "Health storage AIDL HAL joining...";
     ABinderProcess_joinThreadPool();
+
+    LOG(ERROR) << "Health storage AIDL HAL join thread ends, exiting...";
     return EXIT_FAILURE;  // should not reach
 }
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
new file mode 100644
index 0000000..311e951
--- /dev/null
+++ b/health/utils/libhealthshim/Android.bp
@@ -0,0 +1,78 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+    name: "libhealthshim_defaults",
+    host_supported: true, // for testing
+    defaults: [
+        "libbinder_ndk_host_user",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    static_libs: [
+        "android.hardware.health-V1-ndk",
+        "android.hardware.health-translate-ndk",
+        "android.hardware.health@1.0",
+        "android.hardware.health@2.0",
+    ],
+    shared_libs: [
+        // These can be expected from the device or from host.
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+// Shim library that wraps a HIDL IHealth object into an AIDL IHealth object.
+cc_library_static {
+    name: "libhealthshim",
+    defaults: ["libhealthshim_defaults"],
+    recovery_available: true,
+    srcs: [
+        "shim.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
+
+cc_test {
+    name: "libhealthshim_test",
+    defaults: ["libhealthshim_defaults"],
+    static_libs: [
+        "libhealthshim",
+        "libgmock",
+    ],
+    srcs: [
+        "test.cpp",
+    ],
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: true,
+    },
+}
diff --git a/health/utils/libhealthshim/include/health-shim/shim.h b/health/utils/libhealthshim/include/health-shim/shim.h
new file mode 100644
index 0000000..f36fa5d
--- /dev/null
+++ b/health/utils/libhealthshim/include/health-shim/shim.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <map>
+
+#include <aidl/android/hardware/health/BnHealth.h>
+#include <android/hardware/health/2.0/IHealth.h>
+
+namespace aidl::android::hardware::health {
+
+// Shim that wraps HIDL IHealth with an AIDL BnHealth.
+// The wrapper always have isRemote() == false because it is BnHealth.
+class HealthShim : public BnHealth {
+    using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+    using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+
+  public:
+    explicit HealthShim(const ::android::sp<HidlHealth>& service);
+
+    ndk::ScopedAStatus registerCallback(
+            const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+    ndk::ScopedAStatus unregisterCallback(
+            const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+    ndk::ScopedAStatus update() override;
+    ndk::ScopedAStatus getChargeCounterUah(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCurrentNowMicroamps(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCurrentAverageMicroamps(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCapacity(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getEnergyCounterNwh(int64_t* _aidl_return) override;
+    ndk::ScopedAStatus getChargeStatus(BatteryStatus* _aidl_return) override;
+    ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* _aidl_return) override;
+    ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* _aidl_return) override;
+    ndk::ScopedAStatus getHealthInfo(HealthInfo* _aidl_return) override;
+
+  private:
+    ::android::sp<HidlHealth> service_;
+    std::map<std::shared_ptr<IHealthInfoCallback>, ::android::sp<HidlHealthInfoCallback>>
+            callback_map_;
+};
+
+}  // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
new file mode 100644
index 0000000..1329679
--- /dev/null
+++ b/health/utils/libhealthshim/shim.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/hardware/health/translate-ndk.h>
+#include <health-shim/shim.h>
+
+using ::android::sp;
+using ::android::h2a::translate;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::health::V2_0::Result;
+using ::android::hardware::health::V2_0::toString;
+using ::ndk::ScopedAStatus;
+using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlHealthInfo = ::android::hardware::health::V2_0::HealthInfo;
+
+namespace aidl::android::hardware::health {
+
+namespace {
+
+class HealthInfoCallbackShim : public HidlHealthInfoCallback {
+    using AidlHealthInfoCallback = ::aidl::android::hardware::health::IHealthInfoCallback;
+    using AidlHealthInfo = ::aidl::android::hardware::health::HealthInfo;
+
+  public:
+    explicit HealthInfoCallbackShim(const std::shared_ptr<AidlHealthInfoCallback>& impl)
+        : impl_(impl) {}
+    Return<void> healthInfoChanged(const HidlHealthInfo& info) override {
+        AidlHealthInfo aidl_info;
+        // translate() should always return true.
+        CHECK(translate(info, &aidl_info));
+        // This is a oneway function, so we can't (and shouldn't) check for errors.
+        (void)impl_->healthInfoChanged(aidl_info);
+        return Void();
+    }
+
+  private:
+    std::shared_ptr<AidlHealthInfoCallback> impl_;
+};
+
+ScopedAStatus ResultToStatus(Result result) {
+    switch (result) {
+        case Result::SUCCESS:
+            return ScopedAStatus::ok();
+        case Result::NOT_SUPPORTED:
+            return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case Result::UNKNOWN:
+            return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_UNKNOWN);
+        case Result::NOT_FOUND:
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        case Result::CALLBACK_DIED:
+            return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_CALLBACK_DIED);
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            IHealth::STATUS_UNKNOWN, ("Unrecognized result value " + toString(result)).c_str());
+}
+
+template <typename T>
+ScopedAStatus ReturnAndResultToStatus(const Return<T>& ret, Result result) {
+    if (ret.isOk()) {
+        return ResultToStatus(result);
+    }
+    if (ret.isDeadObject()) {
+        return ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(IHealth::STATUS_UNKNOWN,
+                                                              ret.description().c_str());
+}
+
+ScopedAStatus ReturnResultToStatus(const Return<Result>& return_result) {
+    return ReturnAndResultToStatus(return_result, return_result.isOk()
+                                                          ? static_cast<Result>(return_result)
+                                                          : Result::UNKNOWN);
+}
+
+}  // namespace
+
+HealthShim::HealthShim(const sp<HidlHealth>& service) : service_(service) {}
+
+ScopedAStatus HealthShim::registerCallback(
+        const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+    sp<HidlHealthInfoCallback> shim(new HealthInfoCallbackShim(in_callback));
+    callback_map_.emplace(in_callback, shim);
+    return ReturnResultToStatus(service_->registerCallback(shim));
+}
+
+ScopedAStatus HealthShim::unregisterCallback(
+        const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+    auto it = callback_map_.find(in_callback);
+    if (it == callback_map_.end()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    sp<HidlHealthInfoCallback> shim = it->second;
+    callback_map_.erase(it);
+    return ReturnResultToStatus(service_->unregisterCallback(shim));
+}
+
+ScopedAStatus HealthShim::update() {
+    return ReturnResultToStatus(service_->update());
+}
+
+ScopedAStatus HealthShim::getChargeCounterUah(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getChargeCounter([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentNowMicroamps(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCurrentNow([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentAverageMicroamps(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCurrentAverage([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCapacity(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCapacity([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getEnergyCounterNwh(int64_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getEnergyCounter([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getChargeStatus(BatteryStatus* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getChargeStatus([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = static_cast<BatteryStatus>(value);
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getStorageInfo(std::vector<StorageInfo>* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getStorageInfo([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        out->clear();
+        out->reserve(value.size());
+        for (const auto& hidl_info : value) {
+            auto& aidl_info = out->emplace_back();
+            // translate() should always return true.
+            CHECK(translate(hidl_info, &aidl_info));
+        }
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getDiskStats(std::vector<DiskStats>* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getDiskStats([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        out->clear();
+        out->reserve(value.size());
+        for (const auto& hidl_info : value) {
+            auto& aidl_info = out->emplace_back();
+            // translate() should always return true.
+            CHECK(translate(hidl_info, &aidl_info));
+        }
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getHealthInfo(HealthInfo* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getHealthInfo([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        // translate() should always return true.
+        CHECK(translate(value, out));
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+}  // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/test.cpp b/health/utils/libhealthshim/test.cpp
new file mode 100644
index 0000000..d1dfb8b
--- /dev/null
+++ b/health/utils/libhealthshim/test.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <health-shim/shim.h>
+
+#include <android/hardware/health/translate-ndk.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using HidlHealth = android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlStorageInfo = android::hardware::health::V2_0::StorageInfo;
+using HidlDiskStats = android::hardware::health::V2_0::DiskStats;
+using HidlHealthInfo = android::hardware::health::V2_0::HealthInfo;
+using HidlBatteryStatus = android::hardware::health::V1_0::BatteryStatus;
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::health::V2_0::Result;
+using ndk::SharedRefBase;
+using testing::Invoke;
+using testing::NiceMock;
+
+namespace aidl::android::hardware::health {
+MATCHER(IsOk, "") {
+    *result_listener << "status is " << arg.getDescription();
+    return arg.isOk();
+}
+
+MATCHER_P(ExceptionIs, exception_code, "") {
+    *result_listener << "status is " << arg.getDescription();
+    return arg.getExceptionCode() == exception_code;
+}
+
+class MockHidlHealth : public HidlHealth {
+  public:
+    MOCK_METHOD(Return<Result>, registerCallback, (const sp<HidlHealthInfoCallback>& callback),
+                (override));
+    MOCK_METHOD(Return<Result>, unregisterCallback, (const sp<HidlHealthInfoCallback>& callback),
+                (override));
+    MOCK_METHOD(Return<Result>, update, (), (override));
+    MOCK_METHOD(Return<void>, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCapacity, (getCapacity_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getDiskStats, (getDiskStats_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override));
+};
+
+class HealthShimTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        hidl = new NiceMock<MockHidlHealth>();
+        shim = SharedRefBase::make<HealthShim>(hidl);
+    }
+    sp<MockHidlHealth> hidl;
+    std::shared_ptr<IHealth> shim;
+};
+
+#define ADD_TEST(name, aidl_name, AidlValueType, hidl_value, not_supported_hidl_value) \
+    TEST_F(HealthShimTest, name) {                                                     \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                        \
+            cb(Result::SUCCESS, hidl_value);                                           \
+            return Void();                                                             \
+        }));                                                                           \
+        AidlValueType value;                                                           \
+        ASSERT_THAT(shim->aidl_name(&value), IsOk());                                  \
+        ASSERT_EQ(value, static_cast<AidlValueType>(hidl_value));                      \
+    }                                                                                  \
+                                                                                       \
+    TEST_F(HealthShimTest, name##Unsupported) {                                        \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                        \
+            cb(Result::NOT_SUPPORTED, not_supported_hidl_value);                       \
+            return Void();                                                             \
+        }));                                                                           \
+        AidlValueType value;                                                           \
+        ASSERT_THAT(shim->aidl_name(&value), ExceptionIs(EX_UNSUPPORTED_OPERATION));   \
+    }
+
+ADD_TEST(getChargeCounter, getChargeCounterUah, int32_t, 0xFEEDBEEF, 0)
+ADD_TEST(getCurrentNow, getCurrentNowMicroamps, int32_t, 0xC0FFEE, 0)
+ADD_TEST(getCurrentAverage, getCurrentAverageMicroamps, int32_t, 0xA2D401D, 0)
+ADD_TEST(getCapacity, getCapacity, int32_t, 77, 0)
+ADD_TEST(getEnergyCounter, getEnergyCounterNwh, int64_t, 0x1234567887654321, 0)
+ADD_TEST(getChargeStatus, getChargeStatus, BatteryStatus, HidlBatteryStatus::CHARGING,
+         HidlBatteryStatus::UNKNOWN)
+
+#undef ADD_TEST
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) {
+    return ::android::h2a::translate(hidl_value, aidl_value);
+}
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const std::vector<HidlValueType>& hidl_vec, std::vector<AidlValueType>* aidl_vec) {
+    aidl_vec->clear();
+    aidl_vec->reserve(hidl_vec.size());
+    for (const auto& hidl_value : hidl_vec) {
+        auto& aidl_value = aidl_vec->emplace_back();
+        if (!Translate(hidl_value, &aidl_value)) return false;
+    }
+    return true;
+}
+
+#define ADD_INFO_TEST(name, AidlValueType, hidl_value)                               \
+    TEST_F(HealthShimTest, name) {                                                   \
+        AidlValueType expected_aidl_value;                                           \
+        ASSERT_TRUE(Translate(hidl_value, &expected_aidl_value));                    \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([&](auto cb) {                     \
+            cb(Result::SUCCESS, hidl_value);                                         \
+            return Void();                                                           \
+        }));                                                                         \
+        AidlValueType aidl_value;                                                    \
+        ASSERT_THAT(shim->name(&aidl_value), IsOk());                                \
+        ASSERT_EQ(aidl_value, expected_aidl_value);                                  \
+    }                                                                                \
+                                                                                     \
+    TEST_F(HealthShimTest, name##Unsupported) {                                      \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                      \
+            cb(Result::NOT_SUPPORTED, {});                                           \
+            return Void();                                                           \
+        }));                                                                         \
+        AidlValueType aidl_value;                                                    \
+        ASSERT_THAT(shim->name(&aidl_value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
+    }
+
+ADD_INFO_TEST(getStorageInfo, std::vector<StorageInfo>,
+              (std::vector<HidlStorageInfo>{{
+                      .lifetimeA = 15,
+                      .lifetimeB = 18,
+              }}))
+
+ADD_INFO_TEST(getDiskStats, std::vector<DiskStats>,
+              (std::vector<HidlDiskStats>{{
+                      .reads = 100,
+                      .writes = 200,
+              }}))
+
+ADD_INFO_TEST(getHealthInfo, HealthInfo,
+              (HidlHealthInfo{
+                      .batteryCurrentAverage = 999,
+              }))
+
+#undef ADD_INFO_TEST
+
+}  // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthtest/Android.bp b/health/utils/libhealthtest/Android.bp
index dbe02d6..0993cb6 100644
--- a/health/utils/libhealthtest/Android.bp
+++ b/health/utils/libhealthtest/Android.bp
@@ -13,6 +13,15 @@
 // limitations under the License.
 
 // Utils library for VTS tests.
+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_headers {
     name: "libhealthtest_headers",
     static_libs: [
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index a7be660..8e5a0ff 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -41,6 +41,10 @@
         "general-tests",
         "vts",
     ],
+    sanitize: {
+        cfi: false,
+    },
+
 }
 
 cc_test_library {
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 2c15823..7676147 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -81,6 +81,12 @@
 namespace test {
 namespace {
 
+// The maximum number of times we'll attempt to verify that corruption
+// of an encrypted blob results in an error. Retries are necessary as there
+// is a small (roughly 1/256) chance that corrupting ciphertext still results
+// in valid PKCS7 padding.
+constexpr size_t kMaxPaddingCorruptionRetries = 8;
+
 template <TagType tag_type, Tag tag, typename ValueT>
 bool contains(hidl_vec<KeyParameter>& set, TypedTag<tag_type, tag> ttag, ValueT expected_value) {
     size_t count = std::count_if(set.begin(), set.end(), [&](const KeyParameter& param) {
@@ -2853,11 +2859,22 @@
     string ciphertext = EncryptMessage(message, params);
     EXPECT_EQ(16U, ciphertext.size());
     EXPECT_NE(ciphertext, message);
-    ++ciphertext[ciphertext.size() / 2];
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
-    string plaintext;
-    EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &plaintext));
+    for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+        ++ciphertext[ciphertext.size() / 2];
+
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+        string plaintext;
+        ErrorCode error = Finish(message, &plaintext);
+        if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+            // This is the expected error, we can exit the test now.
+            return;
+        } else {
+            // Very small chance we got valid decryption, so try again.
+            ASSERT_EQ(error, ErrorCode::OK);
+        }
+    }
+    FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
 }
 
 HidlBuf CopyIv(const AuthorizationSet& set) {
@@ -3923,17 +3940,30 @@
     string ciphertext = EncryptMessage(message, BlockMode::ECB, PaddingMode::PKCS7);
     EXPECT_EQ(8U, ciphertext.size());
     EXPECT_NE(ciphertext, message);
-    ++ciphertext[ciphertext.size() / 2];
 
     AuthorizationSetBuilder begin_params;
     begin_params.push_back(TAG_BLOCK_MODE, BlockMode::ECB);
     begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
-    string plaintext;
-    size_t input_consumed;
-    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
-    EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
+
+    for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+        ++ciphertext[ciphertext.size() / 2];
+
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        string plaintext;
+
+        size_t input_consumed;
+        EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
+        EXPECT_EQ(ciphertext.size(), input_consumed);
+        ErrorCode error = Finish(&plaintext);
+        if (error == ErrorCode::INVALID_ARGUMENT) {
+            // This is the expected error, we can exit the test now.
+            return;
+        } else {
+            // Very small chance we got valid decryption, so try again.
+            ASSERT_EQ(error, ErrorCode::OK);
+        }
+    }
+    FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
 }
 
 struct TripleDesTestVector {
@@ -4234,18 +4264,28 @@
     string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv);
     EXPECT_EQ(8U, ciphertext.size());
     EXPECT_NE(ciphertext, message);
-    ++ciphertext[ciphertext.size() / 2];
 
     auto begin_params = AuthorizationSetBuilder()
                             .BlockMode(BlockMode::CBC)
                             .Padding(PaddingMode::PKCS7)
                             .Authorization(TAG_NONCE, iv);
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
-    string plaintext;
-    size_t input_consumed;
-    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
-    EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
+    for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+        ++ciphertext[ciphertext.size() / 2];
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        string plaintext;
+        size_t input_consumed;
+        EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
+        EXPECT_EQ(ciphertext.size(), input_consumed);
+        ErrorCode error = Finish(&plaintext);
+        if (error == ErrorCode::INVALID_ARGUMENT) {
+            // This is the expected error, we can exit the test now.
+            return;
+        } else {
+            // Very small chance we got valid decryption, so try again.
+            ASSERT_EQ(error, ErrorCode::OK);
+        }
+    }
+    FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
 }
 
 /*
diff --git a/media/omx/1.0/vts/OWNERS b/media/omx/1.0/vts/OWNERS
index e0e0dd1..9e390c2 100644
--- a/media/omx/1.0/vts/OWNERS
+++ b/media/omx/1.0/vts/OWNERS
@@ -1,7 +1,5 @@
+# Bug component: 25690
 # Media team
-pawin@google.com
+taklee@google.com
+wonsik@google.com
 lajos@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
\ No newline at end of file
diff --git a/neuralnetworks/1.0/utils/OWNERS b/neuralnetworks/1.0/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.0/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
index 1ab9dcb..244001f 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
@@ -41,7 +41,7 @@
 
 // Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
 // function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_OC_MR1. On failure, this function returns with the appropriate
+// nn::kVersionFeatureLevel1. On failure, this function returns with the appropriate
 // nn::GeneralError.
 nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
         ErrorStatus status, const sp<IPreparedModel>& preparedModel);
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
index 5c1480e..7710a7e 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
@@ -28,7 +28,7 @@
 
 namespace android::hardware::neuralnetworks::V1_0::utils {
 
-constexpr auto kVersion = nn::Version::ANDROID_OC_MR1;
+constexpr auto kVersion = nn::kVersionFeatureLevel1;
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
@@ -51,7 +51,7 @@
 template <typename Type>
 nn::Result<void> compliantVersion(const Type& canonical) {
     const auto version = NN_TRY(nn::validate(canonical));
-    if (version > kVersion) {
+    if (!nn::isCompliantVersion(version, kVersion)) {
         return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
     }
     return {};
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index 49913a2..b0c236e 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -99,7 +99,7 @@
 }
 
 nn::Version Device::getFeatureLevel() const {
-    return nn::Version::ANDROID_OC_MR1;
+    return kVersion;
 }
 
 nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.0/utils/test/DeviceTest.cpp b/neuralnetworks/1.0/utils/test/DeviceTest.cpp
index e881da2..83e555f 100644
--- a/neuralnetworks/1.0/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.0/utils/test/DeviceTest.cpp
@@ -233,7 +233,7 @@
     const auto featureLevel = device->getFeatureLevel();
 
     // verify result
-    EXPECT_EQ(featureLevel, nn::Version::ANDROID_OC_MR1);
+    EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel1);
 }
 
 TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.0/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.0/vts/functional/OWNERS b/neuralnetworks/1.0/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.1/utils/OWNERS b/neuralnetworks/1.1/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.1/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
index 4660ff7..ff06739 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
@@ -30,7 +30,7 @@
 namespace android::hardware::neuralnetworks::V1_1::utils {
 
 constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER;
-constexpr auto kVersion = nn::Version::ANDROID_P;
+constexpr auto kVersion = nn::kVersionFeatureLevel2;
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
@@ -53,7 +53,7 @@
 template <typename Type>
 nn::Result<void> compliantVersion(const Type& canonical) {
     const auto version = NN_TRY(nn::validate(canonical));
-    if (version > kVersion) {
+    if (!nn::isCompliantVersion(version, kVersion)) {
         return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
     }
     return {};
diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp
index 7d54cab..3effa84 100644
--- a/neuralnetworks/1.1/utils/src/Device.cpp
+++ b/neuralnetworks/1.1/utils/src/Device.cpp
@@ -99,7 +99,7 @@
 }
 
 nn::Version Device::getFeatureLevel() const {
-    return nn::Version::ANDROID_P;
+    return kVersion;
 }
 
 nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.1/utils/test/DeviceTest.cpp b/neuralnetworks/1.1/utils/test/DeviceTest.cpp
index 41e0e30..2248da6 100644
--- a/neuralnetworks/1.1/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.1/utils/test/DeviceTest.cpp
@@ -243,7 +243,7 @@
     const auto featureLevel = device->getFeatureLevel();
 
     // verify result
-    EXPECT_EQ(featureLevel, nn::Version::ANDROID_P);
+    EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel2);
 }
 
 TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.1/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.1/vts/functional/OWNERS b/neuralnetworks/1.1/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.2/utils/OWNERS b/neuralnetworks/1.2/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.2/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
index 6dd8138..fc04303 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
@@ -38,7 +38,8 @@
 
 // Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
 // function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_Q. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel3. On failure, this function returns with the appropriate
+// nn::GeneralError.
 nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
         V1_0::ErrorStatus status, const sp<IPreparedModel>& preparedModel);
 
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
index 23e336a..a06f2ac 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
@@ -39,7 +39,7 @@
 constexpr auto kDefaultMesaureTiming = MeasureTiming::NO;
 constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits<uint64_t>::max(),
                                   .timeInDriver = std::numeric_limits<uint64_t>::max()};
-constexpr auto kVersion = nn::Version::ANDROID_Q;
+constexpr auto kVersion = nn::kVersionFeatureLevel3;
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
@@ -62,7 +62,7 @@
 template <typename Type>
 nn::Result<void> compliantVersion(const Type& canonical) {
     const auto version = NN_TRY(nn::validate(canonical));
-    if (version > kVersion) {
+    if (!nn::isCompliantVersion(version, kVersion)) {
         return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
     }
     return {};
diff --git a/neuralnetworks/1.2/utils/src/Burst.cpp b/neuralnetworks/1.2/utils/src/Burst.cpp
index e0a23f1..911fbfa 100644
--- a/neuralnetworks/1.2/utils/src/Burst.cpp
+++ b/neuralnetworks/1.2/utils/src/Burst.cpp
@@ -315,7 +315,7 @@
 
     // if the request is valid but of a higher version than what's supported in burst execution,
     // fall back to another execution path
-    if (const auto version = NN_TRY(nn::validate(request)); version > nn::Version::ANDROID_Q) {
+    if (!compliantVersion(request).ok()) {
         // fallback to another execution path if the packet could not be sent
         return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration);
     }
@@ -359,7 +359,7 @@
 
     // if the request is valid but of a higher version than what's supported in burst execution,
     // fall back to another execution path
-    if (const auto version = NN_TRY(nn::validate(request)); version > nn::Version::ANDROID_Q) {
+    if (!compliantVersion(request).ok()) {
         // fallback to another execution path if the packet could not be sent
         return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration);
     }
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index f12669a..e7acecd 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -192,7 +192,7 @@
 }
 
 nn::Version Device::getFeatureLevel() const {
-    return nn::Version::ANDROID_Q;
+    return kVersion;
 }
 
 nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.2/utils/test/DeviceTest.cpp b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
index 215d44c..1dc6285 100644
--- a/neuralnetworks/1.2/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
@@ -483,7 +483,7 @@
     const auto featureLevel = device->getFeatureLevel();
 
     // verify result
-    EXPECT_EQ(featureLevel, nn::Version::ANDROID_Q);
+    EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel3);
 }
 
 TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.2/vts/OWNERS b/neuralnetworks/1.2/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.2/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.2/vts/functional/OWNERS b/neuralnetworks/1.2/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.3/utils/OWNERS b/neuralnetworks/1.3/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.3/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
index 4b8ddc1..10892bc 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
@@ -47,7 +47,8 @@
 
 // Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
 // function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_R. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel4. On failure, this function returns with the appropriate
+// nn::GeneralError.
 nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
         ErrorStatus status, const sp<IPreparedModel>& preparedModel);
 
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
index 2812db2..594d727 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
@@ -39,7 +39,7 @@
 using V1_2::utils::kNoTiming;
 
 constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::ANDROID_R;
+constexpr auto kVersion = nn::kVersionFeatureLevel4;
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
@@ -62,7 +62,7 @@
 template <typename Type>
 nn::Result<void> compliantVersion(const Type& canonical) {
     const auto version = NN_TRY(nn::validate(canonical));
-    if (version > kVersion) {
+    if (!nn::isCompliantVersion(version, kVersion)) {
         return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
     }
     return {};
diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp
index a73ce82..9517fda 100644
--- a/neuralnetworks/1.3/utils/src/Device.cpp
+++ b/neuralnetworks/1.3/utils/src/Device.cpp
@@ -143,7 +143,7 @@
 }
 
 nn::Version Device::getFeatureLevel() const {
-    return nn::Version::ANDROID_R;
+    return kVersion;
 }
 
 nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.3/utils/test/DeviceTest.cpp b/neuralnetworks/1.3/utils/test/DeviceTest.cpp
index 2d1b2f2..7eba4bc 100644
--- a/neuralnetworks/1.3/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.3/utils/test/DeviceTest.cpp
@@ -505,7 +505,7 @@
     const auto featureLevel = device->getFeatureLevel();
 
     // verify result
-    EXPECT_EQ(featureLevel, nn::Version::ANDROID_R);
+    EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel4);
 }
 
 TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.3/vts/OWNERS b/neuralnetworks/1.3/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.3/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.3/vts/functional/OWNERS b/neuralnetworks/1.3/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.3/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/aidl/vts/OWNERS b/neuralnetworks/OWNERS
similarity index 78%
rename from neuralnetworks/aidl/vts/OWNERS
rename to neuralnetworks/OWNERS
index f1a757a..def3ea9 100644
--- a/neuralnetworks/aidl/vts/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,9 +1,10 @@
+# Bug component: 195575
 # Neuralnetworks team
 butlermichael@google.com
 dgross@google.com
+galarragas@google.com
+ianhua@google.com
 jeanluc@google.com
 miaowang@google.com
-mikie@google.com
 pszczepaniak@google.com
 xusongw@google.com
-ianhua@google.com
diff --git a/neuralnetworks/README b/neuralnetworks/README
index d8c8f5d..b0c605d 100644
--- a/neuralnetworks/README
+++ b/neuralnetworks/README
@@ -1,2 +1,2 @@
 NeuralNetworks sample driver implementation is located at
-frameworks/ml/nn/driver/sample.
+packages/modules/NeuralNetworks/driver/sample*.
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index a31157a..cbb6ce5 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -35,5 +35,8 @@
             min_sdk_version: "30",
         },
     },
-    versions: ["1"],
+    versions: [
+        "1",
+        "2",
+    ],
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash
new file mode 100644
index 0000000..35f32ea
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/.hash
@@ -0,0 +1 @@
+04c95c94c96062e5faf35c00b4ae0e50a3f11d0d
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
index 6eadbb7..05cec76 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferDesc.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,8 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable BufferDesc {
+  int[] dimensions;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
index 9bfb725..10a6b75 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/BufferRole.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -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;
-@Backing(type="int") @VintfStability
-enum SapApduType {
-  APDU = 0,
-  APDU7816 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable BufferRole {
+  int modelIndex;
+  int ioIndex;
+  float probability;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
index 0c6c513..30877c0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Capabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,12 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Capabilities {
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
+  android.hardware.neuralnetworks.OperandPerformance[] operandPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo ifPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo whilePerformance;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
similarity index 89%
rename from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
index a03f519..db49a38 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DataLocation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+parcelable DataLocation {
+  int poolIndex;
+  long offset;
+  long length;
+  long padding;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
index a03f519..7cdd6db 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceBuffer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+parcelable DeviceBuffer {
+  android.hardware.neuralnetworks.IBuffer buffer;
+  int token;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
similarity index 90%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
index 6eadbb7..82fe8ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/DeviceType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum DeviceType {
+  OTHER = 1,
+  CPU = 2,
+  GPU = 3,
+  ACCELERATOR = 4,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
similarity index 81%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
index 0c6c513..57d5d6e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ErrorStatus.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,16 @@
 // 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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum ErrorStatus {
+  NONE = 0,
+  DEVICE_UNAVAILABLE = 1,
+  GENERAL_FAILURE = 2,
+  OUTPUT_INSUFFICIENT_SIZE = 3,
+  INVALID_ARGUMENT = 4,
+  MISSED_DEADLINE_TRANSIENT = 5,
+  MISSED_DEADLINE_PERSISTENT = 6,
+  RESOURCE_EXHAUSTED_TRANSIENT = 7,
+  RESOURCE_EXHAUSTED_PERSISTENT = 8,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
index 6eadbb7..4352d8f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionPreference.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum ExecutionPreference {
+  LOW_POWER = 0,
+  FAST_SINGLE_ANSWER = 1,
+  SUSTAINED_SPEED = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
index d7eecbb..44e9922 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExecutionResult.aidl
@@ -31,8 +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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable ExecutionResult {
+  boolean outputSufficientSize;
+  android.hardware.neuralnetworks.OutputShape[] outputShapes;
+  android.hardware.neuralnetworks.Timing timing;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
index d7eecbb..c47028d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Extension.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Extension {
+  String name;
+  android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
index 6eadbb7..6c287fd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionNameAndPrefix {
+  String name;
+  char prefix;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
index 6eadbb7..a3680aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionOperandTypeInformation {
+  char type;
+  boolean isTensor;
+  int byteSize;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
index d7eecbb..7952b34 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable FencedExecutionResult {
+  android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+  @nullable ParcelFileDescriptor syncFence;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
index 6eadbb7..7e61bbb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/FusedActivationFunc.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,11 @@
 // 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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum FusedActivationFunc {
+  NONE = 0,
+  RELU = 1,
+  RELU1 = 2,
+  RELU6 = 3,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
index d7eecbb..f10e7e2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBuffer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBuffer {
+  void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions);
+  void copyTo(in android.hardware.neuralnetworks.Memory dst);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
similarity index 82%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
index d7eecbb..eb3d0b0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IBurst.aidl
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IBurst {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  void releaseMemoryResource(in long memoryIdentifierToken);
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl
new file mode 100644
index 0000000..c9c67f2
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IDevice.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IDevice {
+  android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles);
+  android.hardware.neuralnetworks.Capabilities getCapabilities();
+  android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded();
+  android.hardware.neuralnetworks.Extension[] getSupportedExtensions();
+  boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model);
+  android.hardware.neuralnetworks.DeviceType getType();
+  String getVersionString();
+  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  const int BYTE_SIZE_OF_CACHE_TOKEN = 32;
+  const int MAX_NUMBER_OF_CACHE_FILES = 32;
+  const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15;
+  const int EXTENSION_TYPE_LOW_BITS_TYPE = 16;
+  const int OPERAND_TYPE_BASE_MAX = 65535;
+  const int OPERATION_TYPE_BASE_MAX = 65535;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
index d7eecbb..0bfb80a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,8 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IFencedExecutionCallback {
+  android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
similarity index 67%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
index 0c6c513..fccb5dc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,12 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IPreparedModel {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
+  android.hardware.neuralnetworks.IBurst configureExecutionBurst();
+  const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
+  const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
index d7eecbb..e0c763b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,8 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+interface IPreparedModelCallback {
+  void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
index 6eadbb7..dbedf12 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,8 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable IPreparedModelParcel {
+  android.hardware.neuralnetworks.IPreparedModel preparedModel;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
index d7eecbb..37fa102 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Memory.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union Memory {
+  android.hardware.common.Ashmem ashmem;
+  android.hardware.common.MappableFile mappableFile;
+  android.hardware.graphics.common.HardwareBuffer hardwareBuffer;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
similarity index 79%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
index d7eecbb..30d8dda 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Model.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,13 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Model {
+  android.hardware.neuralnetworks.Subgraph main;
+  android.hardware.neuralnetworks.Subgraph[] referenced;
+  byte[] operandValues;
+  android.hardware.neuralnetworks.Memory[] pools;
+  boolean relaxComputationFloat32toFloat16;
+  android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
index 6eadbb7..9314760 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable NumberOfCacheFiles {
+  int numModelCache;
+  int numDataCache;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
similarity index 75%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
index d7eecbb..1d9bdd8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operand.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,14 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Operand {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  int[] dimensions;
+  float scale;
+  int zeroPoint;
+  android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE;
+  android.hardware.neuralnetworks.DataLocation location;
+  @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
index d7eecbb..14792cf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandExtraParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+union OperandExtraParams {
+  android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant;
+  byte[] extension;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
index 6eadbb7..40adfb1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandLifeTime.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,14 @@
 // 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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum OperandLifeTime {
+  TEMPORARY_VARIABLE = 0,
+  SUBGRAPH_INPUT = 1,
+  SUBGRAPH_OUTPUT = 2,
+  CONSTANT_COPY = 3,
+  CONSTANT_POOL = 4,
+  NO_VALUE = 5,
+  SUBGRAPH = 6,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
index d7eecbb..ebb361b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,9 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable OperandPerformance {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  android.hardware.neuralnetworks.PerformanceInfo info;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
similarity index 77%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
index 0c6c513..9f2c759 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperandType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,15 +31,23 @@
 // 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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum OperandType {
+  FLOAT32 = 0,
+  INT32 = 1,
+  UINT32 = 2,
+  TENSOR_FLOAT32 = 3,
+  TENSOR_INT32 = 4,
+  TENSOR_QUANT8_ASYMM = 5,
+  BOOL = 6,
+  TENSOR_QUANT16_SYMM = 7,
+  TENSOR_FLOAT16 = 8,
+  TENSOR_BOOL8 = 9,
+  FLOAT16 = 10,
+  TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
+  TENSOR_QUANT16_ASYMM = 12,
+  TENSOR_QUANT8_SYMM = 13,
+  TENSOR_QUANT8_ASYMM_SIGNED = 14,
+  SUBGRAPH = 15,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
index 6eadbb7..a4a3fbe 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Operation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Operation {
+  android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD;
+  int[] inputs;
+  int[] outputs;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl
new file mode 100644
index 0000000..2eff11b
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OperationType.aidl
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperationType {
+  ADD = 0,
+  AVERAGE_POOL_2D = 1,
+  CONCATENATION = 2,
+  CONV_2D = 3,
+  DEPTHWISE_CONV_2D = 4,
+  DEPTH_TO_SPACE = 5,
+  DEQUANTIZE = 6,
+  EMBEDDING_LOOKUP = 7,
+  FLOOR = 8,
+  FULLY_CONNECTED = 9,
+  HASHTABLE_LOOKUP = 10,
+  L2_NORMALIZATION = 11,
+  L2_POOL_2D = 12,
+  LOCAL_RESPONSE_NORMALIZATION = 13,
+  LOGISTIC = 14,
+  LSH_PROJECTION = 15,
+  LSTM = 16,
+  MAX_POOL_2D = 17,
+  MUL = 18,
+  RELU = 19,
+  RELU1 = 20,
+  RELU6 = 21,
+  RESHAPE = 22,
+  RESIZE_BILINEAR = 23,
+  RNN = 24,
+  SOFTMAX = 25,
+  SPACE_TO_DEPTH = 26,
+  SVDF = 27,
+  TANH = 28,
+  BATCH_TO_SPACE_ND = 29,
+  DIV = 30,
+  MEAN = 31,
+  PAD = 32,
+  SPACE_TO_BATCH_ND = 33,
+  SQUEEZE = 34,
+  STRIDED_SLICE = 35,
+  SUB = 36,
+  TRANSPOSE = 37,
+  ABS = 38,
+  ARGMAX = 39,
+  ARGMIN = 40,
+  AXIS_ALIGNED_BBOX_TRANSFORM = 41,
+  BIDIRECTIONAL_SEQUENCE_LSTM = 42,
+  BIDIRECTIONAL_SEQUENCE_RNN = 43,
+  BOX_WITH_NMS_LIMIT = 44,
+  CAST = 45,
+  CHANNEL_SHUFFLE = 46,
+  DETECTION_POSTPROCESSING = 47,
+  EQUAL = 48,
+  EXP = 49,
+  EXPAND_DIMS = 50,
+  GATHER = 51,
+  GENERATE_PROPOSALS = 52,
+  GREATER = 53,
+  GREATER_EQUAL = 54,
+  GROUPED_CONV_2D = 55,
+  HEATMAP_MAX_KEYPOINT = 56,
+  INSTANCE_NORMALIZATION = 57,
+  LESS = 58,
+  LESS_EQUAL = 59,
+  LOG = 60,
+  LOGICAL_AND = 61,
+  LOGICAL_NOT = 62,
+  LOGICAL_OR = 63,
+  LOG_SOFTMAX = 64,
+  MAXIMUM = 65,
+  MINIMUM = 66,
+  NEG = 67,
+  NOT_EQUAL = 68,
+  PAD_V2 = 69,
+  POW = 70,
+  PRELU = 71,
+  QUANTIZE = 72,
+  QUANTIZED_16BIT_LSTM = 73,
+  RANDOM_MULTINOMIAL = 74,
+  REDUCE_ALL = 75,
+  REDUCE_ANY = 76,
+  REDUCE_MAX = 77,
+  REDUCE_MIN = 78,
+  REDUCE_PROD = 79,
+  REDUCE_SUM = 80,
+  ROI_ALIGN = 81,
+  ROI_POOLING = 82,
+  RSQRT = 83,
+  SELECT = 84,
+  SIN = 85,
+  SLICE = 86,
+  SPLIT = 87,
+  SQRT = 88,
+  TILE = 89,
+  TOPK_V2 = 90,
+  TRANSPOSE_CONV_2D = 91,
+  UNIDIRECTIONAL_SEQUENCE_LSTM = 92,
+  UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+  RESIZE_NEAREST_NEIGHBOR = 94,
+  QUANTIZED_LSTM = 95,
+  IF = 96,
+  WHILE = 97,
+  ELU = 98,
+  HARD_SWISH = 99,
+  FILL = 100,
+  RANK = 101,
+  BATCH_MATMUL = 102,
+  PACK = 103,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
index 6eadbb7..f733505 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/OutputShape.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable OutputShape {
+  int[] dimensions;
+  boolean isSufficient;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
index 6eadbb7..04910f5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/PerformanceInfo.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable PerformanceInfo {
+  float execTime;
+  float powerUsage;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
similarity index 91%
rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
index 6eadbb7..8f35709 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Priority.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -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;
+package android.hardware.neuralnetworks;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum Priority {
+  LOW = 0,
+  MEDIUM = 1,
+  HIGH = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
index d7eecbb..39ec7a9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Request.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Request {
+  android.hardware.neuralnetworks.RequestArgument[] inputs;
+  android.hardware.neuralnetworks.RequestArgument[] outputs;
+  android.hardware.neuralnetworks.RequestMemoryPool[] pools;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
index d7eecbb..e3541c0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestArgument.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable RequestArgument {
+  boolean hasNoValue;
+  android.hardware.neuralnetworks.DataLocation location;
+  int[] dimensions;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
index a03f519..312f581 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/RequestMemoryPool.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CellIdentityOperatorNames {
-  String alphaLong;
-  String alphaShort;
+union RequestMemoryPool {
+  android.hardware.neuralnetworks.Memory pool;
+  int token;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
similarity index 85%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
index d7eecbb..b7d4451 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Subgraph.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,8 +31,11 @@
 // 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.voice;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable Subgraph {
+  android.hardware.neuralnetworks.Operand[] operands;
+  android.hardware.neuralnetworks.Operation[] operations;
+  int[] inputIndexes;
+  int[] outputIndexes;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
index 6eadbb7..02d68f9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable SymmPerChannelQuantParams {
+  float[] scales;
+  int channelDim;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
similarity index 89%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
index 6eadbb7..bcc83cf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/2/android/hardware/neuralnetworks/Timing.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Timing {
+  long timeOnDeviceNs;
+  long timeInDriverNs;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
index 2eff11b..34506c8 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
@@ -138,4 +138,6 @@
   RANK = 101,
   BATCH_MATMUL = 102,
   PACK = 103,
+  MIRROR_PAD = 104,
+  REVERSE = 105,
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 2ec91ac..aebe8d9 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -4318,6 +4318,8 @@
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16}
      * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM} (since NNAPI feature level 7)
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since NNAPI feature level 7)
      *
      * Supported tensor rank: from 1.
      *
@@ -4326,6 +4328,9 @@
      *
      * Outputs:
      * * 0: The output tensor of same shape as input0.
+     *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+     *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+     *      the scale and zeroPoint can be different from inputs' scale and zeroPoint.
      */
     RSQRT = 83,
 
@@ -5322,4 +5327,68 @@
      * * 0: The packed tensor.
      */
     PACK = 103,
+
+    /**
+     * Pads a tensor with mirrored values.
+     *
+     * Supported tensor {@link OperandType}:
+     * * {@link OperandType::TENSOR_FLOAT16}
+     * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+     * * {@link OperandType::TENSOR_INT32}
+     *
+     * Supported tensor rank: from 1.
+     *
+     * Inputs:
+     * * 0: An n-D tensor, specifying the tensor to be padded.
+     * * 1: A 2-D tensor of {@link OperandType::TENSOR_INT32}, the paddings
+     *      for each spatial dimension of the input tensor. The shape of the
+     *      tensor must be {rank(input0), 2}.
+     *      padding[i, 0] specifies the number of elements to be padded in the
+     *      front of dimension i.
+     *      padding[i, 1] specifies the number of elements to be padded after the
+     *      end of dimension i.
+     * * 2: An {@link OperandType::INT32} scalar, specifying the mode.
+     *      Options are 0:REFLECT and 1:SYMMETRIC.
+     *
+     * Outputs:
+     * * 0: A tensor of the same {@link OperandType} as input0. The
+     *      output tensor has the same rank as input0, and each
+     *      dimension of the output tensor has the same size as the
+     *      corresponding dimension of the input tensor plus the size
+     *      of the padding:
+     *          output0.dimension[i] =
+     *              padding[i, 0] + input0.dimension[i] + padding[i, 1]
+     *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+     *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+     *      the scale and zeroPoint must be the same as input0.
+     */
+    MIRROR_PAD = 104,
+
+    /**
+     * Reverses a specified dimension of a tensor.
+     *
+     * Supported tensor {@link OperandType}:
+     * * {@link OperandType::TENSOR_FLOAT16}
+     * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+     * * {@link OperandType::TENSOR_INT32}
+     *
+     * Supported tensor rank: up to 8.
+     *
+     * Inputs:
+     * * 0: Input tensor of rank n.
+     * * 1: Axis tensor of type {@link OperandType::TENSOR_INT32} and shape [1],
+     *      specifying which dimension of the input tensor is to be reversed. The dimension
+     *      must be in the range [0, n).
+     *
+     * Outputs:
+     * * 0: The reversed tensor.
+     *      For {@link OperandType::TENSOR_QUANT8_ASYMM} and
+     *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors,
+     *      the scales and zeroPoint must be the same as input0.
+     */
+    REVERSE = 105,
 }
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 1a4cd9a..e356104 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -56,13 +56,21 @@
 }
 
 cc_library_static {
-    name: "neuralnetworks_utils_hal_aidl",
+    name: "neuralnetworks_utils_hal_aidl_v2",
     defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
     shared_libs: [
         "android.hardware.neuralnetworks-V2-ndk",
     ],
 }
 
+cc_library_static {
+    name: "neuralnetworks_utils_hal_aidl",
+    defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
+    shared_libs: [
+        "android.hardware.neuralnetworks-V3-ndk",
+    ],
+}
+
 // A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries
 // that are commonly used together. Modules that always depend on the latest non-experimental
 // AIDL features can include this cc_defaults to avoid managing dependency versions explicitly.
@@ -71,7 +79,7 @@
     static_libs: [
         "android.hardware.common-V2-ndk",
         "android.hardware.graphics.common-V3-ndk",
-        "android.hardware.neuralnetworks-V2-ndk",
+        "android.hardware.neuralnetworks-V3-ndk",
         "neuralnetworks_utils_hal_aidl",
     ],
 }
diff --git a/neuralnetworks/aidl/utils/OWNERS b/neuralnetworks/aidl/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/aidl/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h b/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
deleted file mode 100644
index 4421876..0000000
--- a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
+++ /dev/null
@@ -1,17 +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.
- */
-
-#include "nnapi/hal/aidl/BufferTracker.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h b/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
deleted file mode 100644
index 3777969..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
+++ /dev/null
@@ -1,17 +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.
- */
-
-#include "nnapi/hal/aidl/HalInterfaces.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalUtils.h b/neuralnetworks/aidl/utils/include/AidlHalUtils.h
deleted file mode 100644
index 98bfbad..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalUtils.h
+++ /dev/null
@@ -1,17 +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.
- */
-
-#include "nnapi/hal/aidl/HalUtils.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlValidateHal.h b/neuralnetworks/aidl/utils/include/AidlValidateHal.h
deleted file mode 100644
index 5aaa74d..0000000
--- a/neuralnetworks/aidl/utils/include/AidlValidateHal.h
+++ /dev/null
@@ -1,17 +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.
- */
-
-#include "nnapi/hal/aidl/ValidateHal.h"
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index f2ab479..a27487e 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -19,6 +19,7 @@
 
 #include "nnapi/hal/aidl/Conversions.h"
 
+#include <aidl/android/hardware/neuralnetworks/IDevice.h>
 #include <android-base/logging.h>
 #include <nnapi/Result.h>
 #include <nnapi/TypeUtils.h>
@@ -28,7 +29,21 @@
 namespace aidl::android::hardware::neuralnetworks::utils {
 
 constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::FEATURE_LEVEL_6;
+
+constexpr std::optional<nn::Version> aidlVersionToCanonicalVersion(int aidlVersion) {
+    switch (aidlVersion) {
+        case 1:
+            return nn::kVersionFeatureLevel5;
+        case 2:
+            return nn::kVersionFeatureLevel6;
+        case 3:
+            return nn::kVersionFeatureLevel7;
+        default:
+            return std::nullopt;
+    }
+}
+
+constexpr auto kVersion = aidlVersionToCanonicalVersion(IDevice::version).value();
 
 template <typename Type>
 nn::Result<void> validate(const Type& halObject) {
@@ -51,7 +66,7 @@
 template <typename Type>
 nn::Result<void> compliantVersion(const Type& canonical) {
     const auto version = NN_TRY(nn::validate(canonical));
-    if (version > kVersion) {
+    if (!nn::isCompliantVersion(version, kVersion)) {
         return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
     }
     return {};
diff --git a/neuralnetworks/aidl/utils/src/Buffer.cpp b/neuralnetworks/aidl/utils/src/Buffer.cpp
index c729a68..9af3c9e 100644
--- a/neuralnetworks/aidl/utils/src/Buffer.cpp
+++ b/neuralnetworks/aidl/utils/src/Buffer.cpp
@@ -22,7 +22,6 @@
 
 #include "Conversions.h"
 #include "Utils.h"
-#include "nnapi/hal/aidl/Conversions.h"
 
 #include <memory>
 #include <utility>
diff --git a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
rename to neuralnetworks/aidl/utils/src/BufferTracker.cpp
index 15d0810..94dc891 100644
--- a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
+++ b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
-#include "AidlBufferTracker.h"
+#include "BufferTracker.h"
+
+#include "HalInterfaces.h"
 
 #include <android-base/macros.h>
+#include <nnapi/TypeUtils.h>
 
 #include <memory>
 #include <mutex>
@@ -25,9 +28,6 @@
 #include <utility>
 #include <vector>
 
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android::nn {
 
 std::shared_ptr<AidlManagedBuffer> AidlManagedBuffer::create(
diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp
index a321477..8084970 100644
--- a/neuralnetworks/aidl/utils/src/Callbacks.cpp
+++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp
@@ -35,7 +35,8 @@
 
 // Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
 // function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_S. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate
+// nn::GeneralError.
 nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
         ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) {
     HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status);
diff --git a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp b/neuralnetworks/aidl/utils/src/HalUtils.cpp
similarity index 96%
rename from neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
rename to neuralnetworks/aidl/utils/src/HalUtils.cpp
index 6fc46ab..64b6259 100644
--- a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
+++ b/neuralnetworks/aidl/utils/src/HalUtils.cpp
@@ -17,9 +17,12 @@
 // utilities. LegacyUtils.h is the subset of these utilities that do not touch
 // HAL.
 
-#include "AidlHalUtils.h"
+#include "HalUtils.h"
+
+#include "HalInterfaces.h"
 
 #include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
 #include <nnapi/hal/aidl/Conversions.h>
 
 #include <algorithm>
@@ -27,9 +30,6 @@
 #include <type_traits>
 #include <vector>
 
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android::nn {
 
 std::vector<aidl_hal::OperandPerformance> nonExtensionOperandPerformance(
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index 01772ee..e48593c 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -46,13 +46,11 @@
     aidlVersion = std::min(aidlVersion, IDevice::version);
 
     // Map stable AIDL versions to canonical versions.
-    switch (aidlVersion) {
-        case 1:
-            return nn::Version::ANDROID_S;
-        case 2:
-            return nn::Version::FEATURE_LEVEL_6;
+    auto version = aidlVersionToCanonicalVersion(aidlVersion);
+    if (!version.has_value()) {
+        return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
     }
-    return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
+    return version.value();
 }
 
 }  // namespace
diff --git a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
rename to neuralnetworks/aidl/utils/src/ValidateHal.cpp
index a1c496a..a56de21 100644
--- a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
+++ b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
@@ -16,9 +16,12 @@
 
 #define LOG_TAG "ValidateHal"
 
-#include "AidlValidateHal.h"
+#include "ValidateHal.h"
+
+#include "HalUtils.h"
 
 #include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
 #include <nnapi/hal/aidl/Conversions.h>
 
 #include <algorithm>
@@ -27,9 +30,6 @@
 #include <utility>
 #include <vector>
 
-#include "AidlHalUtils.h"
-#include "nnapi/TypeUtils.h"
-
 namespace android {
 namespace nn {
 
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 79abe1b..0366e7d 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -152,13 +152,17 @@
 };
 
 std::string printDeviceTest(const testing::TestParamInfo<nn::Version>& info) {
-    switch (info.param) {
-        case nn::Version::ANDROID_S:
+    const nn::Version version = info.param;
+    CHECK(!version.runtimeOnlyFeatures);
+    switch (version.level) {
+        case nn::Version::Level::FEATURE_LEVEL_5:
             return "v1";
-        case nn::Version::FEATURE_LEVEL_6:
+        case nn::Version::Level::FEATURE_LEVEL_6:
             return "v2";
+        case nn::Version::Level::FEATURE_LEVEL_7:
+            return "v3";
         default:
-            LOG(FATAL) << "Invalid AIDL version: " << info.param;
+            LOG(FATAL) << "Invalid AIDL version: " << version;
             return "invalid";
     }
 }
@@ -891,7 +895,8 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest,
-                         ::testing::Values(nn::Version::ANDROID_S, nn::Version::FEATURE_LEVEL_6),
+                         ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6,
+                                           nn::kVersionFeatureLevel7),
                          printDeviceTest);
 
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index a102fe0..1ed15b8 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -60,6 +60,7 @@
         "libsync",
     ],
     whole_static_libs: [
+        "neuralnetworks_generated_AIDL_V3_example",
         "neuralnetworks_generated_AIDL_V2_example",
         "neuralnetworks_generated_V1_0_example",
         "neuralnetworks_generated_V1_1_example",
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index 1819699..cd5475c 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -28,9 +28,9 @@
 #include <Utils.h>
 #include <nnapi/SharedMemory.h>
 #include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/HalInterfaces.h>
 #include <nnapi/hal/aidl/Utils.h>
 
-#include "AidlHalInterfaces.h"
 #include "Callbacks.h"
 #include "GeneratedTestHarness.h"
 #include "MemoryUtils.h"
diff --git a/neuralnetworks/utils/OWNERS b/neuralnetworks/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
index 3abd724..0488b63 100644
--- a/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
+++ b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
@@ -28,7 +28,6 @@
 namespace {
 
 using ::testing::_;
-using ::testing::InvokeWithoutArgs;
 using ::testing::Return;
 
 using SharedMockDevice = std::shared_ptr<const nn::MockDevice>;
@@ -54,7 +53,7 @@
     // Setup default actions for each relevant call.
     constexpr auto getName_ret = []() -> const std::string& { return kName; };
     constexpr auto getVersionString_ret = []() -> const std::string& { return kVersionString; };
-    constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1;
+    constexpr auto kFeatureLevel = nn::kVersionFeatureLevel1;
     constexpr auto kDeviceType = nn::DeviceType::ACCELERATOR;
     constexpr auto getSupportedExtensions_ret = []() -> const std::vector<nn::Extension>& {
         return kExtensions;
@@ -142,7 +141,7 @@
 TEST(ResilientDeviceTest, getFeatureLevel) {
     // setup call
     const auto [mockDevice, mockDeviceFactory, device] = setup();
-    constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1;
+    constexpr auto kFeatureLevel = nn::kVersionFeatureLevel1;
     EXPECT_CALL(*mockDevice, getFeatureLevel()).Times(1).WillOnce(Return(kFeatureLevel));
 
     // run test
@@ -592,7 +591,7 @@
     const auto recoveredMockDevice = createConfiguredMockDevice();
     EXPECT_CALL(*recoveredMockDevice, getFeatureLevel())
             .Times(1)
-            .WillOnce(Return(nn::Version::ANDROID_P));
+            .WillOnce(Return(nn::kVersionFeatureLevel2));
     EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice));
 
     // run test
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e10d329..9acb9e0 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -24,8 +24,8 @@
 cc_binary {
     name: "android.hardware.power-service.example",
     relative_install_path: "hw",
-    init_rc: ["power-default.rc"],
-    vintf_fragments: ["power-default.xml"],
+    init_rc: [":android.hardware.power.rc"],
+    vintf_fragments: [":android.hardware.power.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
@@ -37,3 +37,13 @@
         "Power.cpp",
     ],
 }
+
+filegroup {
+    name: "android.hardware.power.xml",
+    srcs: ["power-default.xml"],
+}
+
+filegroup {
+    name: "android.hardware.power.rc",
+    srcs: ["power-default.rc"],
+}
diff --git a/power/aidl/default/apex/Android.bp b/power/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..eb04087
--- /dev/null
+++ b/power/aidl/default/apex/Android.bp
@@ -0,0 +1,72 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+apex_key {
+    name: "com.android.hardware.power.key",
+    public_key: "com.android.hardware.power.avbpubkey",
+    private_key: "com.android.hardware.power.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.power.certificate",
+    certificate: "com.android.hardware.power",
+}
+
+genrule {
+    name: "com.android.hardware.power.rc-srcs",
+    srcs: [
+        ":android.hardware.power.rc",
+        ":android.hardware.power.stats.rc",
+    ],
+    out: ["com.android.hardware.power.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.power/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.power.rc",
+    src: ":com.android.hardware.power.rc-srcs",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.power",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.power.key",
+    certificate: ":com.android.hardware.power.certificate",
+    file_contexts: "file_contexts",
+    use_vndk_as_stable: true,
+    updatable: false,
+    // Install the apex in /vendor/apex
+    soc_specific: true,
+    // Bundle the Power and PowerStats HALs into this one APEX.
+    binaries: [
+        "android.hardware.power-service.example",
+        "android.hardware.power.stats-service.example",
+    ],
+    prebuilts: [
+        "com.android.hardware.power.rc",
+    ],
+    vintf_fragments: [
+        ":android.hardware.power.xml",
+        ":android.hardware.power.stats.xml",
+    ],
+    overrides: [
+        // Shared lib installed by default but unused by the AIDL implementation.
+        "power.default",
+    ],
+}
diff --git a/power/aidl/default/apex/apex_manifest.json b/power/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..faa937d
--- /dev/null
+++ b/power/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.power",
+  "version": 1
+}
diff --git a/power/aidl/default/apex/com.android.hardware.power.avbpubkey b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
new file mode 100644
index 0000000..3b6411d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.pem b/power/aidl/default/apex/com.android.hardware.power.pem
new file mode 100644
index 0000000..d18ae98
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAsUdFjtLq05tWKdQd4aj8V7tmV4KXw41pKGT5Q1CPzrdHF3yJ
+B/8VWdMpjZ+eQO1q8SijPgfvWExeWQVMfxKmwTmj26xWXhIOgo5G02Zva7zOptig
+KGnl/RdFlOiIGC36XeWDhzdIOhlGv+er9Sykf6Ot84OvktTBUTZNJrXQsyYTBRUX
+6B+wloPdBVxVf1HgzjeHUyCy5dTz0xZSWWELoW24tHIvV5FtJVKSY8ZDfuXWLLfT
+he7E93TepjT027U/J/iW4ITJzw4Qq87ick1D/jZDUbTrkqUMFEgPdgCouZ9zt5xG
+pcHAZ/Fcz9DZfEdX9Xy0R5/XbfrJdvDPguJlwK1pZnr/Pe13xxmE+TEohMmaQDqX
+jQNX3UlcfOYUAjnFMGucHDM10KjTMbP8ytCys88aNLiv7FOgVGrQ/djZN8rkMyVP
+ccoksUBMQmjYaQQZ2yZuJMiLD3P6aYkgU5tMEMoMTrBzfcx05GfElal+ZqOFKAzj
+eUxoZTR27wJb684FRbeE45D+y4jpFfrTEXry+aI7GrfDsVDnUqmyObCUttRtaT04
+6kuUmC44wFEg1EBfcWZc1szI192GBjMuZjFcYvJ4vMdCuennqvLNPBDY1PtqzCOf
+D8vpOE3T9rjS23xxFmmSmorwKKQOGChKqO/SaY0axkXgt+FbSsvTBQtZTSsCAwEA
+AQKCAgEArEu3t+MYJcdwS8EDtcF2V5IkGmMrOvziOkdA14Kh8efBKXt49xOc3atU
+VHfQ6AuXh4DWf0BZB7lZbS2wNkSbW2q47ZSmcFEeVxcOkQGawtxDAHfD2ONrirqm
+ft4s/0sYbU/WsIEzKnxMfdEdGHFmA0PCmczfxFYQ+OxMuZW1m5ginirtDEZYa0EH
+e+FMmyypz+K6HDnIhYWd4Aduy718/0zTWlUr2/DUYpTJAD2+dcPNj7Kt2xq/xj2I
+84K+hBa4phF+GgIU3a8u1ryA61RbA+QbM3siBWlxvvh2RlrHoXjuj4JMS2dup9c2
+PCggaCAyxb2IvaAFUbePPJE5LVz6RFT4HnLEydd5Yt+CEAm+iZKfCzyUgFRtb5y0
+HHTME1eVAt/rf/yIXUYA7q8nQ/PtSzIol5KLX4FUjX1MVKNmIWMa+836kxbuYDFB
+K1M1IKc1k0t9Q9F3TRCMhP/6qH/vJfubCGQhSRUMq7JyjivK9GjYST8R07Dpgu9Z
+4i9TRI8d+UVERsg8niCXONVkmNa3U49u2duUvqV3KmKgQ/Hgyy3keDjz6x56ie5w
+e0EusHAsot60W1BvHrdwlmGZjW3JmZEyazUPh9nBUAaQve1rIOpn80kGXx4EAE2o
+HcrcInJx/zVBk1Wk3UQDwmhUNpa64q9+nd9VMaR9SQNK3ah4NDECggEBAOeput2F
+CgRrvzka69i7FbgY4VmpNMIICPIB6gxvwpir/g4/GgYknuBB6ep1ksf/IZfsMp5A
+JTH1KdXqqQm8nV9v+ETYQAO+VnmWKSBKHsNJqONxsKkQ+xIJcusmKBTYLfL88XQg
+YWH3VMXgqPP8DnJYCeVRIKj1WqfEFFHiaLJJB8FgKhtZBwBnibkVG1K0XCkTdUfY
+mME2GRKW/C7DMvuFOpcFVj7Obwn68R2k3zsOhWA5NQGZF5mqhg5KYLVDg3IbMJQQ
+D+DymQxnc2s2ar0q24isy1Y/FOXrA057j1vAN951+pk6F/PCJM/mtAiRjhP0Aru1
+P6bbR11p+wnpU7MCggEBAMPm8Jmwu3F0xsyFC+1sWPAzPiwaMa7/30wANNKKqHVO
+7lUv1WYFbFMyAOzYPp3Y5HxdxNa43reULGk0R20kSu6W6FkApSvAws0rLKRlS5UI
+oZqhLGHUH2M7q07m2RgQY2TJkU2Zq6AH1kjcbSr127ISXKanKpqonwSHy38BTcGt
+Dl2fVioPzK/vwmiNo2njhh95TV4kqlbUfl7xtDt56tbg8oFBwOsK7UGajXYOxTGB
+o1DtO5E+oiOmlclXuo3m4qpSSMv+wM91aRFhHZVIx0vmO8y5lrfU2kM/5DDhJBxV
+FM4TaA+c5tFOTuCLejHc7nM99wVx7O4QZ0wBwETUxKkCggEAH0tBT+1J1iEL+tXV
+KDjVjUHnJyqBUvis5Kw3hqiOO/t33UrO5CeMQrUEuURaqKOhURl6GQCHRcFdfmUt
+ooAVLjA89GfV9et/WPtc4NzCXRUVOGxCNgRyNhSKrpM/9NjjFCDxKQO6w/YaQITB
+rfvNo8qaw5x68ff64BDPweP4yqSs5IVuCrWzCW3zH8pnH3v3uyDCxgrPT8JUDrvQ
+oyyBNZLgwEfbR66xN0Lr0VpVQXALulzf+TBKDNsJMuL/P104Y3Ci1k15J6T94bwT
+zlbSgm1IrKTS7vqkgw6FKtPsILPNmEKNsKc1VxtRx7fdeA7Zh3595Adu6sZSVJ8d
+Z1BamwKCAQAnbu0vgqu4gtEhigaEnDKq5yW0qvElUMwZ+FCpsM+IDYNcEmzaRG0x
+sfcNtdmk3GvhvN5KepwaR/FInAVkqtGKhUXv5Hla/Uo5El/CF8HHFh2xio/sgU5w
+IyqwjzdT6LiZKRnejPhHFkzEDdrLswGuLpQH185zo02fE9aakiCcw8EIh3JItTV2
+lMSFVz11qx7sZvZz5N2E7PEjG3Q0JK5o4o7uBdZXebOYaQvgn8iB1p6RQ6+h5QGu
+O3IbPVWICtnFfxq4NWeKWw/zN6FE04mKdaXD5/e2uVnV/55nWGp0aYvuj2l6+xJb
+P3ARMwI910MIX4jBx9TxdsvUOOYC9PFBAoIBAQDWswLnaNth4pgutngVWbMenSpv
+eK1RA1ldw2NoTZrGlqPB+LvjEMSH/7ioby8YtOyJRIWs3si8HpVF12qneu8qi7b7
+QlUtqyJOTnGalvhrlq5zPhdW+kk2DXvtTylUnz3vSxxi2I7cLhQRryLC/1kAwy67
+wEr0+u59bOvaqe8L1zgtYJpLQZeskUMzdSMIRVDdFShEFrMJU7adUvGpA7OZ6Ogf
+ux2jWr2vv/eKq6fU6kDPi/66MQjPbZPf2Uq6+XedkNkAeELpN4o3hw0/l/rfiK/r
+YUMJBwtjQw/hehtvC4GlgsH1tMZWzCZULo0tcW4qbzyi9PBrWFPteb33OjBc
+-----END RSA PRIVATE KEY-----
diff --git a/power/aidl/default/apex/com.android.hardware.power.pk8 b/power/aidl/default/apex/com.android.hardware.power.pk8
new file mode 100644
index 0000000..e45435d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pk8
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.x509.pem b/power/aidl/default/apex/com.android.hardware.power.x509.pem
new file mode 100644
index 0000000..9f0c5f0
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8ECFDFsXbm5CdS/UtQZgTiF8Umr8LrLMA0GCSqGSIb3DQEBCwUAMIGn
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEjMCEGA1UEAwwaY29t
+LmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwIBcNMjExMDIwMTcwNTA0WhgPNDc1OTA5
+MTYxNzA1MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
+MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
+CwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEj
+MCEGA1UEAwwaY29tLmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwggIiMA0GCSqGSIb3
+DQEBAQUAA4ICDwAwggIKAoICAQC/37fhOkOfgM2e+M7bMJ1baLFif8dKGwRa6mkJ
+9HWmuOgRcTKllzuEHtrJ0jzur3cDy6/0oZSfA/E1ck3DdRHMQadW26JSNSg6fCU9
+h1kDzkakZgyr3DsJnKGoSHCJ2V2kVbCnd6GuOaOU1ZZISw1I+BWJDc3t1mZPs80D
+ar7/hoIZnsWRoE/eWgJDcWWscRsquSi+q6hyqlCbRvwRznPaDGwmb4geHNugCXkz
+EtCswfc5jiT8DjMDkgVsGO/WcYj2GWT0K0H+Zf1CmEO9fAoXTLfVBjdumtGILgii
+d/TJe2tOBSWyZz6sVzfac2PvUH5Lm8TNUXuLV5IEdcpySge0vqYQwAyd2EgsTH1e
+mRNSk9NerpmfCFEySRRP3BWMGRhbST1d8M3v9Bq0QFhrxoAF12r6GXBUpp9XcOL5
+pBTcAkA9XI++mfz4pDzyGRGOy4WX+8XtsaVZ/14JklupSLr0Tt7oaNocUhoXB03g
+4B0jUTX0hNnVzCxzJypw6YJ60Zc8z+z8pEF34FWarHec1QbkFuyWxbaTPQ4d2NLH
+8zDxQpMILErWdAgKsRL0d8RFG5fBcleEoBM2kKHMAgnP+1qyDqBgt8zloWbmmblw
+JXMuoePFOgeVcgPrZ3EGJSx+s4+dQGQc6r/GwKLKSWpUvHxTIGug76IX9xmptB+I
+F3xb2QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQANISf3Vi2eueOlzzfnEGGa+CXz
+nvlgUXKv8Gv0/Pbg5uC1BaHTAUgRu5rvrfP9p3Mdj86I/HbE/F4Vkuzqb8/JTWGA
+mG636zAsJRJr0fnkbPma9wVEPSK8MF1QqM6PmKXboixX82TqV1R1sRYG+9hh9W3u
+isDzYDb2ODE0X9M8/3hLS28zdCdtl4zCRK6KB86aGxvkVEj4qDA5l+AbVYevS/SU
+hz1+K/aM0Fi6MZovo5kd/Mof5l05e1TEgCoL1FtFX79r+PYGHJ8/LjtEMkFgwqvG
+CLx2sOV09EHZU27EbVvSs1JYMMXgeAvKaHsVZ51QlSzW4esg/E6z4pw654p8qyK/
+WLXIZ7BMILl1sHYmGqXitnu19puvNks2/+hyqVr0seM5GyQDuwBE8nx6xZzTRxdj
+4TZyN9LuMc9/cKJFvOPqD152bkA2frCLEzYCQreDWwxsWcUHzYrQT+v2SqzP6Ue2
+Xn06HDLx9wBL7Dz6no05SlNS0u1KdvKas6FKZHO+QaKKsBlDmXbMrBTcuUI6OXv2
+6NpVbeyDd0+A23hDiNSgI6zTY6jMidesNExB7rW/bCE4ltPyxFAB+sffyXounODc
+groB5CaS2bv+H1IXJzMMe4LkgQPl1C7G+I3KvJmnrYwmIhLIDuxP82arClIDzccS
+ExRR7ugEg91XCc87Zg==
+-----END CERTIFICATE-----
diff --git a/power/aidl/default/apex/file_contexts b/power/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..3433851
--- /dev/null
+++ b/power/aidl/default/apex/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                                      u:object_r:vendor_file:s0
+/bin/hw/android\.hardware\.power-service\.example           u:object_r:hal_power_default_exec:s0
+/bin/hw/android\.hardware\.power\.stats-service\.example    u:object_r:hal_power_stats_default_exec:s0
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 7c0caf3..66be5f9 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -24,8 +24,8 @@
 cc_binary {
     name: "android.hardware.power.stats-service.example",
     relative_install_path: "hw",
-    init_rc: ["power.stats-default.rc"],
-    vintf_fragments: ["power.stats-default.xml"],
+    init_rc: [":android.hardware.power.stats.rc"],
+    vintf_fragments: [":android.hardware.power.stats.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
@@ -37,3 +37,13 @@
         "PowerStats.cpp",
     ],
 }
+
+filegroup {
+    name: "android.hardware.power.stats.xml",
+    srcs: ["power.stats-default.xml"],
+}
+
+filegroup {
+    name: "android.hardware.power.stats.rc",
+    srcs: ["power.stats-default.rc"],
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 44f9865..9f530b3 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -612,6 +612,9 @@
         EXPECT_EQ(0, cardStatus.applications.size());
     }
 
+    // Give some time for modem to fully power down the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
     /* Test setSimCardPower power up */
     serial = GetRandomSerialNumber();
     radio_v1_6->setSimCardPower_1_6(serial, CardPowerState::POWER_UP);
@@ -624,6 +627,9 @@
                                   ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
                                   ::android::hardware::radio::V1_6::RadioError::SIM_ERR}));
 
+    // Give some time for modem to fully power up the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
     // setSimCardPower_1_6 does not return  until the request is handled. Just verify that we still
     // have CardState::PRESENT after turning the power back on
     if (radioRsp_v1_6->rspInfo.error == ::android::hardware::radio::V1_6::RadioError::NONE) {
@@ -639,6 +645,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
@@ -693,6 +703,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
@@ -746,6 +760,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 54c2977..f041865 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -47,6 +47,7 @@
 
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
 
 #define RADIO_SERVICE_SLOT1_NAME "slot1"  // HAL instance name for SIM slot 1 or single SIM device
 #define RADIO_SERVICE_SLOT2_NAME "slot2"  // HAL instance name for SIM slot 2 on dual SIM device
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
index 2cfb8d0..5cc9017 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
@@ -36,7 +36,5 @@
 parcelable SimPortInfo {
   String iccId;
   int logicalSlotId;
-  int portState;
-  const int PORT_STATE_INACTIVE = 0;
-  const int PORT_STATE_ACTIVE = 1;
+  boolean portActive;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index 60eabc7..bc7f63c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -34,7 +34,6 @@
 package android.hardware.radio.config;
 @VintfStability
 parcelable SimSlotStatus {
-  boolean cardActive;
   int cardState;
   String atr;
   String eid;
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 cfcd42c..9df687c 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
@@ -52,6 +52,7 @@
   int mtuV6;
   boolean preferred;
   boolean persistent;
+  boolean alwaysOn;
   const int ID_DEFAULT = 0;
   const int ID_TETHERED = 1;
   const int ID_IMS = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
index 0febcd1..0dd8127 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
@@ -37,7 +37,7 @@
   byte sliceServiceType;
   int sliceDifferentiator;
   byte mappedHplmnSst;
-  int mappedHplmnSD;
+  int mappedHplmnSd;
   byte status;
   const byte SERVICE_TYPE_NONE = 0;
   const byte SERVICE_TYPE_EMBB = 1;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
index 7dd1341..8c1fdfa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -39,5 +39,5 @@
   int baseStationId;
   int longitude;
   int latitude;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
index 3991af7..2e384e9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -40,6 +40,6 @@
   int cid;
   int arfcn;
   byte bsic;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
index 9ea0974..c83997e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
@@ -40,7 +40,7 @@
   int pci;
   int tac;
   int earfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   int bandwidth;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
index 865e0dd..6bdfd99 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
@@ -40,7 +40,7 @@
   int pci;
   int tac;
   int nrarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   android.hardware.radio.network.NgranBands[] bands;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 836b5b5..4100805 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -40,7 +40,7 @@
   int cid;
   int cpid;
   int uarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
index f832449..907f30d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -40,7 +40,7 @@
   int cid;
   int psc;
   int uarfcn;
-  android.hardware.radio.network.CellIdentityOperatorNames operatorNames;
+  android.hardware.radio.network.OperatorInfo operatorNames;
   String[] additionalPlmns;
   @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index bfb8061..16433be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -42,7 +42,6 @@
   oneway void getCellInfoList(in int serial);
   oneway void getDataRegistrationState(in int serial);
   oneway void getImsRegistrationState(in int serial);
-  oneway void getNeighboringCids(in int serial);
   oneway void getNetworkSelectionMode(in int serial);
   oneway void getOperator(in int serial);
   oneway void getSignalStrength(in int serial);
@@ -50,7 +49,6 @@
   oneway void getVoiceRadioTechnology(in int serial);
   oneway void getVoiceRegistrationState(in int serial);
   oneway void isNrDualConnectivityEnabled(in int serial);
-  oneway void pullLceData(in int serial);
   oneway void responseAcknowledgement();
   oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
   oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index e03e4df..ff95396 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -43,7 +43,6 @@
   oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellInfo[] cellInfo);
   oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult dataRegResponse);
   oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily);
-  oneway void getNeighboringCidsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.NeighboringCell[] cells);
   oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual);
   oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric);
   oneway void getSignalStrengthResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.SignalStrength signalStrength);
@@ -51,7 +50,6 @@
   oneway void getVoiceRadioTechnologyResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioTechnology rat);
   oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult voiceRegResponse);
   oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
-  oneway void pullLceDataResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.LceDataInfo lceInfo);
   oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
index 948a1f6..1e657e5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -41,6 +41,7 @@
   boolean incrementalResults;
   int incrementalResultsPeriodicity;
   String[] mccMncs;
+  const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
   const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MIN = 1;
   const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MAX = 10;
   const int MAX_SEARCH_TIME_RANGE_MIN = 60;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
index cc5a53e..85a0c71 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
@@ -53,11 +53,10 @@
   oneway void iccTransmitApduLogicalChannel(in int serial, in android.hardware.radio.sim.SimApdu message);
   oneway void reportStkServiceIsRunning(in int serial);
   oneway void requestIccSimAuthentication(in int serial, in int authContext, in String authData, in String aid);
-  oneway void requestIsimAuthentication(in int serial, in String challenge);
   oneway void responseAcknowledgement();
-  oneway void sendEnvelope(in int serial, in String command);
+  oneway void sendEnvelope(in int serial, in String contents);
   oneway void sendEnvelopeWithStatus(in int serial, in String contents);
-  oneway void sendTerminalResponseToSim(in int serial, in String commandResponse);
+  oneway void sendTerminalResponseToSim(in int serial, in String contents);
   oneway void setAllowedCarriers(in int serial, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy);
   oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo);
   oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSub);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
index e164257..8e68e30 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -54,7 +54,6 @@
   oneway void iccTransmitApduLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result);
   oneway void reportStkServiceIsRunningResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void requestIccSimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result);
-  oneway void requestIsimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in String response);
   oneway void sendEnvelopeResponse(in android.hardware.radio.RadioResponseInfo info, in String commandResponse);
   oneway void sendEnvelopeWithStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo);
   oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index 579dd29..b373aa5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable CdmaDisplayInfoRecord {
   String alphaBuf;
+  const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 6648358..cc4d3fa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -42,6 +42,7 @@
   android.hardware.radio.voice.CdmaLineControlInfoRecord[] lineCtrl;
   android.hardware.radio.voice.CdmaT53ClirInfoRecord[] clir;
   android.hardware.radio.voice.CdmaT53AudioControlInfoRecord[] audioCtrl;
+  const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
   const int NAME_DISPLAY = 0;
   const int NAME_CALLED_PARTY_NUMBER = 1;
   const int NAME_CALLING_PARTY_NUMBER = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index f3fcb2f..26a7df5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -39,4 +39,5 @@
   byte numberPlan;
   byte pi;
   byte si;
+  const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
index d48102b..744e7ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable CfData {
   android.hardware.radio.voice.CallForwardInfo[] cfInfo;
+  const int NUM_SERVICE_CLASSES = 7;
 }
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 4cac560..68c82fa 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
@@ -53,6 +53,7 @@
   oneway void hangup(in int serial, in int gsmIndex);
   oneway void hangupForegroundResumeBackground(in int serial);
   oneway void hangupWaitingOrBackground(in int serial);
+  oneway void isVoNrEnabled(in int serial);
   oneway void rejectCall(in int serial);
   oneway void responseAcknowledgement();
   oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
@@ -66,6 +67,7 @@
   oneway void setPreferredVoicePrivacy(in int serial, in boolean enable);
   oneway void setResponseFunctions(in android.hardware.radio.voice.IRadioVoiceResponse radioVoiceResponse, in android.hardware.radio.voice.IRadioVoiceIndication radioVoiceIndication);
   oneway void setTtyMode(in int serial, in android.hardware.radio.voice.TtyMode mode);
+  oneway void setVoNrEnabled(in int serial, in boolean enable);
   oneway void startDtmf(in int serial, in String s);
   oneway void stopDtmf(in int serial);
   oneway void switchWaitingOrHoldingAndActive(in int serial);
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 4f87c12..af3417d 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
@@ -37,7 +37,7 @@
   oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.voice.CdmaSignalInfoRecord record);
   oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type);
   oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord);
-  oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecords records);
+  oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecord[] records);
   oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaOtaProvisionStatus status);
   oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList);
   oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
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 9f490a8..a3b5e58 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
@@ -54,6 +54,7 @@
   oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
   oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
@@ -65,6 +66,7 @@
   oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setTtyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
index c5ba293..9517847 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 parcelable SsInfoData {
   int[] ssInfo;
+  const int SS_INFO_MAX = 4;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl
deleted file mode 100644
index 2a111c6..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl
+++ /dev/null
@@ -1,46 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.radio;
-@VintfStability
-interface ISap {
-  oneway void apduReq(in int token, in android.hardware.radio.SapApduType type, in byte[] command);
-  oneway void connectReq(in int token, in int maxMsgSize);
-  oneway void disconnectReq(in int token);
-  oneway void powerReq(in int token, in boolean state);
-  oneway void resetSimReq(in int token);
-  oneway void setCallback(in android.hardware.radio.ISapCallback sapCallback);
-  oneway void setTransferProtocolReq(in int token, in android.hardware.radio.SapTransferProtocol transferProtocol);
-  oneway void transferAtrReq(in int token);
-  oneway void transferCardReaderStatusReq(in int token);
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl
deleted file mode 100644
index 5ae0392..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl
+++ /dev/null
@@ -1,48 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.radio;
-@VintfStability
-interface ISapCallback {
-  oneway void apduResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] apduRsp);
-  oneway void connectResponse(in int token, in android.hardware.radio.SapConnectRsp sapConnectRsp, in int maxMsgSize);
-  oneway void disconnectIndication(in int token, in android.hardware.radio.SapDisconnectType disconnectType);
-  oneway void disconnectResponse(in int token);
-  oneway void errorResponse(in int token);
-  oneway void powerResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-  oneway void resetSimResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-  oneway void statusIndication(in int token, in android.hardware.radio.SapStatus status);
-  oneway void transferAtrResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] atr);
-  oneway void transferCardReaderStatusResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in int cardReaderStatus);
-  oneway void transferProtocolResponse(in int token, in android.hardware.radio.SapResultCode resultCode);
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
index 10a956e..9bb17fe 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
@@ -52,6 +52,7 @@
   HSPAP = 32768,
   GSM = 65536,
   TD_SCDMA = 131072,
+  IWLAN = 262144,
   LTE_CA = 524288,
   NR = 1048576,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
index d111a0d..f411ca2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
@@ -32,21 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
-enum RadioConst {
-  CDMA_ALPHA_INFO_BUFFER_LENGTH = 64,
-  CDMA_NUMBER_INFO_BUFFER_LENGTH = 81,
-  MAX_RILDS = 3,
-  MAX_SOCKET_NAME_LENGTH = 6,
-  MAX_CLIENT_ID_LENGTH = 2,
-  MAX_DEBUG_SOCKET_NAME_LENGTH = 12,
-  MAX_QEMU_PIPE_NAME_LENGTH = 11,
-  MAX_UUID_LENGTH = 64,
-  CARD_MAX_APPS = 8,
-  CDMA_MAX_NUMBER_OF_INFO_RECS = 10,
-  SS_INFO_MAX = 4,
-  NUM_SERVICE_CLASSES = 7,
-  NUM_TX_POWER_LEVELS = 5,
-  RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8,
-  P2_CONSTANT_NO_P2 = -1,
+@VintfStability
+parcelable RadioConst {
+  const int MAX_RILDS = 3;
+  const int MAX_UUID_LENGTH = 64;
+  const int CARD_MAX_APPS = 8;
+  const int P2_CONSTANT_NO_P2 = -1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl
deleted file mode 100644
index 7e4d246..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl
+++ /dev/null
@@ -1,42 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.radio;
-@Backing(type="int") @VintfStability
-enum SapConnectRsp {
-  SUCCESS = 0,
-  CONNECT_FAILURE = 1,
-  MSG_SIZE_TOO_LARGE = 2,
-  MSG_SIZE_TOO_SMALL = 3,
-  CONNECT_OK_CALL_ONGOING = 4,
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl
deleted file mode 100644
index e0d8eb2..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl
+++ /dev/null
@@ -1,39 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.radio;
-@Backing(type="int") @VintfStability
-enum SapDisconnectType {
-  GRACEFUL = 0,
-  IMMEDIATE = 1,
-}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl
deleted file mode 100644
index 715c507..0000000
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl
+++ /dev/null
@@ -1,43 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.radio;
-@Backing(type="int") @VintfStability
-enum SapStatus {
-  UNKNOWN_ERROR = 0,
-  CARD_RESET = 1,
-  CARD_NOT_ACCESSIBLE = 2,
-  CARD_REMOVED = 3,
-  CARD_INSERTED = 4,
-  RECOVERED = 5,
-}
diff --git a/radio/aidl/android/hardware/radio/ISap.aidl b/radio/aidl/android/hardware/radio/ISap.aidl
deleted file mode 100644
index 1ca4fe7..0000000
--- a/radio/aidl/android/hardware/radio/ISap.aidl
+++ /dev/null
@@ -1,95 +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;
-
-import android.hardware.radio.ISapCallback;
-import android.hardware.radio.SapApduType;
-import android.hardware.radio.SapTransferProtocol;
-
-/**
- * Empty top level interface.
- */
-@VintfStability
-oneway interface ISap {
-    /**
-     * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param type APDU command type
-     * @param command CommandAPDU/CommandAPDU7816 parameter depending on type
-     */
-    void apduReq(in int token, in SapApduType type, in byte[] command);
-
-    /**
-     * CONNECT_REQ from SAP 1.1 spec 5.1.1
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param maxMsgSize MaxMsgSize to be used for SIM Access Profile connection
-     */
-    void connectReq(in int token, in int maxMsgSize);
-
-    /**
-     * DISCONNECT_REQ from SAP 1.1 spec 5.1.3
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void disconnectReq(in int token);
-
-    /**
-     * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param state true for on, false for off
-     */
-    void powerReq(in int token, in boolean state);
-
-    /**
-     * RESET_SIM_REQ from SAP 1.1 spec 5.1.14
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void resetSimReq(in int token);
-
-    /**
-     * Set callback that has response and unsolicited indication functions
-     *
-     * @param sapCallback Object containing response and unosolicited indication callbacks
-     */
-    void setCallback(in ISapCallback sapCallback);
-
-    /**
-     * SET_TRANSPORT_PROTOCOL_REQ from SAP 1.1 spec 5.1.20
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     * @param transferProtocol Transport Protocol
-     */
-    void setTransferProtocolReq(in int token, in SapTransferProtocol transferProtocol);
-
-    /**
-     * TRANSFER_ATR_REQ from SAP 1.1 spec 5.1.8
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void transferAtrReq(in int token);
-
-    /**
-     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.17
-     *
-     * @param token Id to match req-resp. Resp must include same token.
-     */
-    void transferCardReaderStatusReq(in int token);
-}
diff --git a/radio/aidl/android/hardware/radio/ISapCallback.aidl b/radio/aidl/android/hardware/radio/ISapCallback.aidl
deleted file mode 100644
index 00e543b..0000000
--- a/radio/aidl/android/hardware/radio/ISapCallback.aidl
+++ /dev/null
@@ -1,152 +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;
-
-import android.hardware.radio.SapConnectRsp;
-import android.hardware.radio.SapDisconnectType;
-import android.hardware.radio.SapResultCode;
-import android.hardware.radio.SapStatus;
-
-@VintfStability
-oneway interface ISapCallback {
-    /**
-     * TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED
-     * @param apduRsp APDU Response. Valid only if command was processed correctly and no error
-     *        occurred.
-     */
-    void apduResponse(in int token, in SapResultCode resultCode, in byte[] apduRsp);
-
-    /**
-     * CONNECT_RESP from SAP 1.1 spec 5.1.2
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param sapConnectRsp Connection Status
-     * @param maxMsgSize MaxMsgSize supported by server if request cannot be fulfilled.
-     *        Valid only if connectResponse is SapConnectResponse:MSG_SIZE_TOO_LARGE.
-     */
-    void connectResponse(in int token, in SapConnectRsp sapConnectRsp, in int maxMsgSize);
-
-    /**
-     * DISCONNECT_IND from SAP 1.1 spec 5.1.5
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param disconnectType Disconnect Type to indicate if shutdown is graceful or immediate
-     */
-    void disconnectIndication(in int token, in SapDisconnectType disconnectType);
-
-    /**
-     * DISCONNECT_RESP from SAP 1.1 spec 5.1.4
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     */
-    void disconnectResponse(in int token);
-
-    /**
-     * ERROR_RESP from SAP 1.1 spec 5.1.19
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     */
-    void errorResponse(in int token);
-
-    /**
-     * POWER_SIM_OFF_RESP and POWER_SIM_ON_RESP from SAP 1.1 spec 5.1.11 + 5.1.13
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE, (possible only for power on req)
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF, (possible only for power off req)
-     *        SapResultCode:CARD_REMOVED,
-     *        SapResultCode:CARD_ALREADY_POWERED_ON (possible only for power on req)
-     */
-    void powerResponse(in int token, in SapResultCode resultCode);
-
-    /**
-     * RESET_SIM_RESP from SAP 1.1 spec 5.1.15
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_NOT_ACCESSSIBLE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED
-     */
-    void resetSimResponse(in int token, in SapResultCode resultCode);
-
-    /**
-     * STATUS_IND from SAP 1.1 spec 5.1.16
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param status Parameter to indicate reason for the status change.
-     */
-    void statusIndication(in int token, in SapStatus status);
-
-    /**
-     * TRANSFER_ATR_RESP from SAP 1.1 spec 5.1.9
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE,
-     *        SapResultCode:CARD_ALREADY_POWERED_OFF,
-     *        SapResultCode:CARD_REMOVED,
-     *        SapResultCode:DATA_NOT_AVAILABLE
-     * @param atr Answer to Reset from the subscription module. Included only if no error occurred,
-     *        otherwise empty.
-     */
-    void transferAtrResponse(in int token, in SapResultCode resultCode, in byte[] atr);
-
-    /**
-     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.18
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS,
-     *        SapResultCode:GENERIC_FAILURE
-     *        SapResultCode:DATA_NOT_AVAILABLE
-     * @param cardReaderStatus Card Reader Status coded as described in 3GPP TS 11.14 Section 12.33
-     *        and TS 31.111 Section 8.33
-     */
-    void transferCardReaderStatusResponse(
-            in int token, in SapResultCode resultCode, in int cardReaderStatus);
-
-    /**
-     * SET_TRANSPORT_PROTOCOL_RESP from SAP 1.1 spec 5.1.21
-     *
-     * @param token Id to match req-resp. Value must match the one in req.
-     * @param resultCode ResultCode to indicate if command was processed correctly
-     *        Possible values:
-     *        SapResultCode:SUCCESS
-     *        SapResultCode:NOT_SUPPORTED
-     */
-    void transferProtocolResponse(in int token, in SapResultCode resultCode);
-}
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 719837d..b8fbf9b 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -39,6 +39,7 @@
     HSPAP = 1 << RadioTechnology.HSPAP,
     GSM = 1 << RadioTechnology.GSM,
     TD_SCDMA = 1 << RadioTechnology.TD_SCDMA,
+    IWLAN = 1 << RadioTechnology.IWLAN,
     LTE_CA = 1 << RadioTechnology.LTE_CA,
     /**
      * 5G NR. This is only use in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl
index 2e1bcf0..cd03f84 100644
--- a/radio/aidl/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/android/hardware/radio/RadioConst.aidl
@@ -17,24 +17,12 @@
 package android.hardware.radio;
 
 @VintfStability
-@Backing(type="int")
-enum RadioConst {
-    CDMA_ALPHA_INFO_BUFFER_LENGTH = 64,
-    CDMA_NUMBER_INFO_BUFFER_LENGTH = 81,
-    MAX_RILDS = 3,
-    MAX_SOCKET_NAME_LENGTH = 6,
-    MAX_CLIENT_ID_LENGTH = 2,
-    MAX_DEBUG_SOCKET_NAME_LENGTH = 12,
-    MAX_QEMU_PIPE_NAME_LENGTH = 11,
-    MAX_UUID_LENGTH = 64,
-    CARD_MAX_APPS = 8,
-    CDMA_MAX_NUMBER_OF_INFO_RECS = 10,
-    SS_INFO_MAX = 4,
-    NUM_SERVICE_CLASSES = 7,
-    NUM_TX_POWER_LEVELS = 5,
-    RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8,
+parcelable RadioConst {
+    const int MAX_RILDS = 3;
+    const int MAX_UUID_LENGTH = 64;
+    const int CARD_MAX_APPS = 8;
     /**
      * No P2 value is provided
      */
-    P2_CONSTANT_NO_P2 = -1,
+    const int P2_CONSTANT_NO_P2 = -1;
 }
diff --git a/radio/aidl/android/hardware/radio/SapApduType.aidl b/radio/aidl/android/hardware/radio/SapApduType.aidl
deleted file mode 100644
index f697e58..0000000
--- a/radio/aidl/android/hardware/radio/SapApduType.aidl
+++ /dev/null
@@ -1,24 +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;
-
-@VintfStability
-@Backing(type="int")
-enum SapApduType {
-    APDU,
-    APDU7816,
-}
diff --git a/radio/aidl/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/android/hardware/radio/SapConnectRsp.aidl
deleted file mode 100644
index d2046d2..0000000
--- a/radio/aidl/android/hardware/radio/SapConnectRsp.aidl
+++ /dev/null
@@ -1,27 +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;
-
-@VintfStability
-@Backing(type="int")
-enum SapConnectRsp {
-    SUCCESS,
-    CONNECT_FAILURE,
-    MSG_SIZE_TOO_LARGE,
-    MSG_SIZE_TOO_SMALL,
-    CONNECT_OK_CALL_ONGOING,
-}
diff --git a/radio/aidl/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/android/hardware/radio/SapDisconnectType.aidl
deleted file mode 100644
index 30a04bd..0000000
--- a/radio/aidl/android/hardware/radio/SapDisconnectType.aidl
+++ /dev/null
@@ -1,24 +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;
-
-@VintfStability
-@Backing(type="int")
-enum SapDisconnectType {
-    GRACEFUL,
-    IMMEDIATE,
-}
diff --git a/radio/aidl/android/hardware/radio/SapResultCode.aidl b/radio/aidl/android/hardware/radio/SapResultCode.aidl
deleted file mode 100644
index db87374..0000000
--- a/radio/aidl/android/hardware/radio/SapResultCode.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;
-
-@VintfStability
-@Backing(type="int")
-enum SapResultCode {
-    SUCCESS,
-    GENERIC_FAILURE,
-    CARD_NOT_ACCESSSIBLE,
-    CARD_ALREADY_POWERED_OFF,
-    CARD_REMOVED,
-    CARD_ALREADY_POWERED_ON,
-    DATA_NOT_AVAILABLE,
-    NOT_SUPPORTED,
-}
diff --git a/radio/aidl/android/hardware/radio/SapStatus.aidl b/radio/aidl/android/hardware/radio/SapStatus.aidl
deleted file mode 100644
index 0a6b4a7..0000000
--- a/radio/aidl/android/hardware/radio/SapStatus.aidl
+++ /dev/null
@@ -1,28 +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;
-
-@VintfStability
-@Backing(type="int")
-enum SapStatus {
-    UNKNOWN_ERROR,
-    CARD_RESET,
-    CARD_NOT_ACCESSIBLE,
-    CARD_REMOVED,
-    CARD_INSERTED,
-    RECOVERED,
-}
diff --git a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
index 78f1309..54b9890 100644
--- a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
@@ -34,18 +34,10 @@
      * Logical slot id is identifier of the active slot
      */
     int logicalSlotId;
-    /*
-     * Port is Inactive
-     * Inactive means logical modem is no longer associated to the port
-     */
-    const int PORT_STATE_INACTIVE = 0;
-    /*
-     * Port is Active
-     * Active means logical modem is associated to the port
-     */
-    const int PORT_STATE_ACTIVE = 1;
     /**
-     * Port state in the slot. Values are portState.[PORT_STATE_INACTIVE, PORT_STATE_ACTIVE].
+     * Port active status in the slot.
+     * Inactive means logical modem is no longer associated to the port.
+     * Active means logical modem is associated to the port.
      */
-    int portState;
+    boolean portActive;
 }
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 4ab955a..a1c3c27 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -20,7 +20,6 @@
 
 @VintfStability
 parcelable SimSlotStatus {
-    boolean cardActive;
     /**
      * Card state in the physical slot. Values are CardStatus.[STATE_ABSENT, STATE_PRESENT,
      * STATE_ERROR, STATE_RESTRICTED].
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 7657fc9..a14963f 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -115,4 +115,11 @@
      * If the same data profile exists, this data profile must overwrite it.
      */
     boolean persistent;
+    /**
+     * Indicates the PDU session brought up by this data profile should be always-on.
+     * An always-on PDU Session is a PDU Session for which User Plane resources have to be
+     * activated during every transition from CM-IDLE mode to CM-CONNECTED state.
+     * See 3GPP TS 23.501 section 5.6.13 for the details.
+     */
+    boolean alwaysOn;
 }
diff --git a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
index dd315e8..0943031 100644
--- a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
@@ -83,7 +83,7 @@
      * value. A value of -1 indicates that there is no corresponding SliceInfo of the HPLMN.
      * See: 3GPP TS 24.501 Section 9.11.2.8.
      */
-    int mappedHplmnSD;
+    int mappedHplmnSd;
     /**
      * Field to indicate the current status of the slice.
      * Values are STATUS_
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index e271e50..ae6fda4 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityCdma {
@@ -44,5 +44,8 @@
      * (corresponding to a range of -90 to +90 degrees). INT_MAX if unknown
      */
     int latitude;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
index 7b711ad..75a96e8 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityGsm {
@@ -44,7 +44,10 @@
      * 6-bit Base Station Identity Code, 0xFF if unknown
      */
     byte bsic;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
index d4f83a3..ae52cf2 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
@@ -16,9 +16,9 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
 import android.hardware.radio.network.EutranBands;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityLte {
@@ -46,7 +46,10 @@
      * 18-bit LTE Absolute RF Channel Number; this value must be valid
      */
     int earfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Cell bandwidth, in kHz.
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
index dfccbf7..73a56ea 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.NgranBands;
+import android.hardware.radio.network.OperatorInfo;
 
 /**
  * The CellIdentity structure should be reported once for each element of the PLMN-IdentityInfoList
@@ -55,7 +55,10 @@
      * This value must be valid.
      */
     int nrarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 99c8151..5b00df1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityTdscdma {
@@ -45,7 +45,10 @@
      * 16-bit UMTS Absolute RF Channel Number defined in TS 25.102 5.4.4; this value must be valid.
      */
     int uarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell.
      */
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
index 302be96..bf4d6cb 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.radio.network;
 
-import android.hardware.radio.network.CellIdentityOperatorNames;
 import android.hardware.radio.network.ClosedSubscriberGroupInfo;
+import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
 parcelable CellIdentityWcdma {
@@ -45,7 +45,10 @@
      * 16-bit UMTS Absolute RF Channel Number; this value must be valid.
      */
     int uarfcn;
-    CellIdentityOperatorNames operatorNames;
+    /**
+     * OperatorInfo containing alphaLong and alphaShort
+     */
+    OperatorInfo operatorNames;
     /**
      * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell.
      */
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index ffc97f3..1081a75 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -114,15 +114,6 @@
     void getImsRegistrationState(in int serial);
 
     /**
-     * Request neighboring cell id in GSM network
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioNetworkResponse.getNeighboringCidsResponse()
-     */
-    void getNeighboringCids(in int serial);
-
-    /**
      * Query current network selection mode
      *
      * @param serial Serial number of request.
@@ -187,15 +178,6 @@
     void isNrDualConnectivityEnabled(in int serial);
 
     /**
-     * Pull LCE service for capacity information.
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioNetworkResponse.pullLceDataResponse()
-     */
-    void pullLceData(in int serial);
-
-    /**
      * When response type received from a radio indication or radio response is
      * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively,
      * acknowledge the receipt of those messages by sending responseAcknowledgement().
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index ae2646d..429b5a8 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -179,25 +179,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param cells Vector of neighboring radio cell
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:NO_MEMORY
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:MODEM_ERR
-     *   RadioError:NO_NETWORK_FOUND
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     */
-    void getNeighboringCidsResponse(in RadioResponseInfo info, in NeighboringCell[] cells);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      * @param selection false for automatic selection, true for manual selection
      *
      * Valid errors returned:
@@ -299,23 +280,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param lceInfo LceDataInfo indicating LCE data
-     *
-     * Valid errors returned:
-     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:LCE_NOT_SUPPORTED
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_MEMORY
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     *   RadioError:SIM_ABSENT
-     */
-    void pullLceDataResponse(in RadioResponseInfo info, in LceDataInfo lceInfo);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
index ec8aa95..7cea1de 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -20,6 +20,8 @@
 
 @VintfStability
 parcelable NetworkScanRequest {
+    const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
+
     const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MIN = 1;
     const int INCREMENTAL_RESULTS_PREIODICITY_RANGE_MAX = 10;
 
@@ -50,7 +52,7 @@
     int interval;
     /**
      * Networks with bands/channels to scan.
-     * Maximum length of the vector is RadioConst:RADIO_ACCESS_SPECIFIER_MAX_SIZE.
+     * Maximum length of the vector is RADIO_ACCESS_SPECIFIER_MAX_SIZE.
      */
     RadioAccessSpecifier[] specifiers;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index bd681e7..312182e 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -32,10 +32,11 @@
      */
     RegState regState;
     /**
-     * Indicates the available voice radio technology, valid values as defined by RadioTechnology,
-     * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on
-     * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig
-     * elements through IRadioNetwork::currentPhysicalChannelConfigs.
+     * Indicates the radio technology (except LTE_CA, which is no longer a valid value), which
+     * must not be UNKNOWN if regState is REG_HOME, REG_ROAMING, NOT_REG_MT_NOT_SEARCHING_OP_EM,
+     * NOT_REG_MT_SEARCHING_OP_EM, REG_DENIED_EM, or UNKNOWN_EM.
+     * When the device is on carrier aggregation, vendor RIL service must properly report multiple
+     * PhysicalChannelConfig elements through IRadioNetwork::currentPhysicalChannelConfigs.
      */
     RadioTechnology rat;
     /**
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 902c90c..c731caf 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -262,17 +262,6 @@
             in int serial, in int authContext, in String authData, in String aid);
 
     /**
-     * Request the ISIM application on the UICC to perform AKA challenge/response algorithm
-     * for IMS authentication
-     *
-     * @param serial Serial number of request.
-     * @param challenge challenge string in Base64 format
-     *
-     * Response function is IRadioSimResponse.requestIsimAuthenticationResponse()
-     */
-    void requestIsimAuthentication(in int serial, in String challenge);
-
-    /**
      * When response type received from a radio indication or radio response is
      * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively,
      * acknowledge the receipt of those messages by sending responseAcknowledgement().
@@ -284,11 +273,11 @@
      * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111
      *
      * @param serial Serial number of request.
-     * @param command SAT/USAT command in hexadecimal format string starting with command tag
+     * @param contents SAT/USAT command in hexadecimal format string starting with command tag
      *
      * Response function is IRadioSimResponse.sendEnvelopeResponse()
      */
-    void sendEnvelope(in int serial, in String command);
+    void sendEnvelope(in int serial, in String contents);
 
     /**
      * Requests to send a SAT/USAT envelope command to SIM. The SAT/USAT envelope command refers to
@@ -309,12 +298,12 @@
      * Requests to send a terminal response to SIM for a received proactive command
      *
      * @param serial Serial number of request.
-     * @param commandResponse SAT/USAT response in hexadecimal format string starting with
+     * @param contents SAT/USAT response in hexadecimal format string starting with
      *        first byte of response data
      *
      * Response function is IRadioSimResponse.sendTerminalResponseResponseToSim()
      */
-    void sendTerminalResponseToSim(in int serial, in String commandResponse);
+    void sendTerminalResponseToSim(in int serial, in String contents);
 
     /**
      * Set carrier restrictions. Expected modem behavior:
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index dcc7029..750a29a 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -365,24 +365,6 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param response response string of the challenge/response algo for ISIM auth in base64 format
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_MEMORY
-     *   RadioError:NO_RESOURCES
-     *   RadioError:CANCELLED
-     *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:SIM_ABSENT
-     */
-    void requestIsimAuthenticationResponse(in RadioResponseInfo info, in String response);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      * @param commandResponse SAT/USAT response in hexadecimal format string starting with first
      *        byte of response
      *
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index 18a1ce4..ac66237 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -25,8 +25,9 @@
  */
 @VintfStability
 parcelable CdmaDisplayInfoRecord {
+    const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
     /**
-     * Max length = RadioConst:CDMA_ALPHA_INFO_BUFFER_LENGTH
+     * Max length = CDMA_ALPHA_INFO_BUFFER_LENGTH
      */
     String alphaBuf;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
index af37dac..6920462 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -25,7 +25,11 @@
 import android.hardware.radio.voice.CdmaT53ClirInfoRecord;
 
 @VintfStability
+/**
+ * Max length of CdmaInformationRecords[] is CDMA_MAX_NUMBER_OF_INFO_RECS
+ */
 parcelable CdmaInformationRecord {
+    const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
     /**
      * Names of the CDMA info records (C.S0005 section 3.7.5)
      */
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index 41ce08f..265bf67 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -23,8 +23,9 @@
  */
 @VintfStability
 parcelable CdmaNumberInfoRecord {
+    const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
     /**
-     * Max length = RadioConst::CDMA_NUMBER_INFO_BUFFER_LENGTH
+     * Max length = CDMA_NUMBER_INFO_BUFFER_LENGTH
      */
     String number;
     byte numberType;
diff --git a/radio/aidl/android/hardware/radio/voice/CfData.aidl b/radio/aidl/android/hardware/radio/voice/CfData.aidl
index 8d7c4bd..f28c7c8 100644
--- a/radio/aidl/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CfData.aidl
@@ -20,9 +20,10 @@
 
 @VintfStability
 parcelable CfData {
+    const int NUM_SERVICE_CLASSES = 7;
     /**
      * This is the response data for SS request to query call forward status.
-     * See getCallForwardStatus(). Max size = RadioConst:NUM_SERVICE_CLASSES.
+     * See getCallForwardStatus(). Max size = NUM_SERVICE_CLASSES.
      */
     CallForwardInfo[] cfInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index 1e60de5..a012be4 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -267,6 +267,15 @@
     void hangupWaitingOrBackground(in int serial);
 
     /**
+     * Query current Voice NR enable state
+     *
+     * @param serial Serial number of request.
+     *
+     * Response function is IRadioVoiceResponse.isVoNrEnabledResponse()
+     */
+    void isVoNrEnabled(in int serial);
+
+    /**
      * Send UDUB (user determined user busy) to ringing or waiting call answer)
      *
      * @param serial Serial number of request.
@@ -404,6 +413,16 @@
     void setTtyMode(in int serial, in TtyMode mode);
 
     /**
+     * Set Voice NR enable state
+     *
+     * @param serial Serial number of request.
+     * @param enable true for "enable vonr" and false for "disable vonr"
+     *
+     * Response function is IRadioVoiceResponse.setVoNrEnabledResponse()
+     */
+    void setVoNrEnabled(in int serial, in boolean enable);
+
+    /**
      * Start playing a DTMF tone. Continue playing DTMF tone until stopDtmf is received. If a
      * startDtmf() is received while a tone is currently playing, it must cancel the previous tone
      * and play the new one.
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 81640f3..25e87b3 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -18,7 +18,7 @@
 
 import android.hardware.radio.RadioIndicationType;
 import android.hardware.radio.voice.CdmaCallWaiting;
-import android.hardware.radio.voice.CdmaInformationRecords;
+import android.hardware.radio.voice.CdmaInformationRecord;
 import android.hardware.radio.voice.CdmaOtaProvisionStatus;
 import android.hardware.radio.voice.CdmaSignalInfoRecord;
 import android.hardware.radio.voice.EmergencyNumber;
@@ -67,9 +67,10 @@
      * Indicates when CDMA radio receives one or more info recs.
      *
      * @param type Type of radio indication
-     * @param records New Cdma Information
+     * @param records New CDMA information records.
+     *        Max length is RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
      */
-    void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecords records);
+    void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecord[] records);
 
     /**
      * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call.
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index f3cf5fb..d126fc1 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -468,6 +468,20 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
+     * @param enable true for "vonr enabled" and false for "vonr disabled"
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void isVoNrEnabledResponse(in RadioResponseInfo info, in boolean enable);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -694,6 +708,20 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void setVoNrEnabledResponse(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_RESOURCES
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
diff --git a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
index 40af393..d562925 100644
--- a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
@@ -18,11 +18,12 @@
 
 @VintfStability
 parcelable SsInfoData {
+    const int SS_INFO_MAX = 4;
     /**
      * This is the response data for all of the SS GET/SET Radio requests.
      * E.g. IRadioVoice.getClir() returns two ints, so first two values of ssInfo[] will be used for
      * response if serviceType is SS_CLIR and requestType is SS_INTERROGATION.
-     * Max size = RadioConst:SS_INFO_MAX
+     * Max size = SS_INFO_MAX
      */
     int[] ssInfo;
 }
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
new file mode 100644
index 0000000..43d9378
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -0,0 +1,93 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "android.hardware.radio-library.compat",
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        //"-Wold-style-cast",  // TODO(b/203699028) enable after aosp/1900880 gets merged
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+    ],
+    shared_libs: [
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio@1.0",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.5",
+        "android.hardware.radio@1.6",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+    ],
+    srcs: [
+        "RadioCompatBase.cpp",
+        "RadioResponse.cpp",
+        "commonStructs.cpp",
+        "config/RadioConfig.cpp",
+        "config/RadioConfigIndication.cpp",
+        "config/RadioConfigResponse.cpp",
+        "config/structs.cpp",
+        "data/RadioIndication-data.cpp",
+        "data/RadioResponse-data.cpp",
+        "data/RadioData.cpp",
+        "data/structs.cpp",
+        "messaging/RadioIndication-messaging.cpp",
+        "messaging/RadioMessaging.cpp",
+        "messaging/RadioResponse-messaging.cpp",
+        "messaging/structs.cpp",
+        "modem/RadioIndication-modem.cpp",
+        "modem/RadioResponse-modem.cpp",
+        "modem/RadioModem.cpp",
+        "modem/structs.cpp",
+        "network/RadioIndication-network.cpp",
+        "network/RadioNetwork.cpp",
+        "network/RadioResponse-network.cpp",
+        "network/structs.cpp",
+        "network/utils.cpp",
+        "sim/RadioIndication-sim.cpp",
+        "sim/RadioResponse-sim.cpp",
+        "sim/RadioSim.cpp",
+        "sim/structs.cpp",
+        "voice/RadioIndication-voice.cpp",
+        "voice/RadioResponse-voice.cpp",
+        "voice/RadioVoice.cpp",
+        "voice/structs.cpp",
+    ],
+    export_include_dirs: ["include"],
+}
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
new file mode 100644
index 0000000..a9eac68
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioCompatBase.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+                                 sp<RadioIndication> radioIndication)
+    : mHal1_5(hidlHal),
+      mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
+      mRadioResponse(radioResponse),
+      mRadioIndication(radioIndication) {}
+
+V1_6::IRadioResponse& RadioCompatBase::respond() {
+    CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
+    return *mRadioResponse;
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
new file mode 100644
index 0000000..35b0ac1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "debug.h"
+
+#define RADIO_MODULE "Common"
+
+namespace android::hardware::radio::compat {
+
+Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
+    if (mDataCb) mDataCb->acknowledgeRequest(serial);
+    if (mMessagingCb) mMessagingCb->acknowledgeRequest(serial);
+    if (mModemCb) mModemCb->acknowledgeRequest(serial);
+    if (mNetworkCb) mNetworkCb->acknowledgeRequest(serial);
+    if (mSimCb) mSimCb->acknowledgeRequest(serial);
+    if (mVoiceCb) mVoiceCb->acknowledgeRequest(serial);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/collections.h b/radio/aidl/compat/libradiocompat/collections.h
new file mode 100644
index 0000000..082ef17
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/collections.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <hidl/HidlSupport.h>
+
+#include <type_traits>
+#include <variant>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * Converts hidl_vec<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toAidl(const hidl_vec<T>& inp) {
+    std::vector<decltype(toAidl(T{}))> out(inp.size());
+    for (size_t i = 0; i < inp.size(); i++) {
+        out[i] = toAidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts std::vector<T> AIDL list to hidl_vec<T> HIDL list.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toHidl(const std::vector<T>& inp) {
+    hidl_vec<decltype(toHidl(T{}))> out(inp.size());
+    for (size_t i = 0; i < inp.size(); i++) {
+        out[i] = toHidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts hidl_array<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp array to convert
+ */
+template <typename T, size_t N>
+auto toAidl(const hidl_array<T, N>& inp) {
+    std::vector<decltype(toAidl(T{}))> out(N);
+    for (size_t i = 0; i < N; i++) {
+        out[i] = toAidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::optional<X> AIDL value.
+ *
+ * To convert values, the template uses toAidl functions for a given type T.value.
+ */
+template <typename T>
+std::optional<decltype(toAidl(T{}.value()))> toAidl(const T& opt) {
+    if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return std::nullopt;
+    return toAidl(opt.value());
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::variant<bool, X> AIDL value.
+ *
+ * For some reason, not every OptionalX gets generated into a std::optional<X>.
+ */
+template <typename T>
+std::variant<bool, decltype(toAidl(T{}.value()))> toAidlVariant(const T& opt) {
+    if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return false;
+    return toAidl(opt.value());
+}
+
+/**
+ * Converts std::optional<X> AIDL value to T=OptionalX HIDL value.
+ *
+ * X is inferred from toAidl(T.value) declaration. Please note that toAidl(T.value) doesn't have to
+ * be implemented if it's not needed for anything else than giving this hint to type system.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param opt value to convert
+ */
+template <typename T>
+T toHidl(const std::optional<decltype(toAidl(T{}.value()))>& opt) {
+    T hidl;
+    if (opt.has_value()) hidl.value(toHidl(*opt));
+    return hidl;
+}
+
+/**
+ * Converts U AIDL bitfield value to HIDL T bitfield value.
+ *
+ * \param val value to convert
+ */
+template <typename T, typename U>
+hidl_bitfield<T> toHidlBitfield(U val) {
+    return static_cast<int>(val);
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
new file mode 100644
index 0000000..c25768d
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "commonStructs.h"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+V1_6::RadioResponseInfo notSupported(int32_t serial) {
+    return {
+            .type = V1_0::RadioResponseType::SOLICITED,
+            .serial = serial,
+            .error = V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+    };
+}
+
+std::string toAidl(const hidl_string& str) {
+    return str;
+}
+
+hidl_string toHidl(const std::string& str) {
+    return str;
+}
+
+uint8_t toAidl(int8_t v) {
+    return v;
+}
+
+int8_t toAidl(uint8_t v) {
+    return v;
+}
+
+int32_t toAidl(uint32_t v) {
+    return v;
+}
+
+aidl::RadioIndicationType toAidl(V1_0::RadioIndicationType type) {
+    return aidl::RadioIndicationType(type);
+}
+
+aidl::RadioResponseType toAidl(V1_0::RadioResponseType type) {
+    return aidl::RadioResponseType(type);
+}
+
+aidl::RadioError toAidl(V1_0::RadioError err) {
+    return aidl::RadioError(err);
+}
+
+aidl::RadioError toAidl(V1_6::RadioError err) {
+    return aidl::RadioError(err);
+}
+
+aidl::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info) {
+    return {
+            .type = toAidl(info.type),
+            .serial = info.serial,
+            .error = toAidl(info.error),
+    };
+}
+
+aidl::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info) {
+    return {
+            .type = toAidl(info.type),
+            .serial = info.serial,
+            .error = toAidl(info.error),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
new file mode 100644
index 0000000..b859916
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/RadioIndicationType.h>
+#include <aidl/android/hardware/radio/RadioResponseInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_6::RadioResponseInfo notSupported(int32_t serial);
+
+std::string toAidl(const hidl_string& str);
+hidl_string toHidl(const std::string& str);
+uint8_t toAidl(int8_t v);
+int8_t toAidl(uint8_t v);
+int32_t toAidl(uint32_t v);
+
+aidl::android::hardware::radio::RadioIndicationType toAidl(V1_0::RadioIndicationType type);
+aidl::android::hardware::radio::RadioResponseType toAidl(V1_0::RadioResponseType type);
+aidl::android::hardware::radio::RadioError toAidl(V1_0::RadioError type);
+aidl::android::hardware::radio::RadioError toAidl(V1_6::RadioError type);
+
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info);
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
new file mode 100644
index 0000000..d0d6f7a
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioConfig.h>
+
+#include "RadioConfigIndication.h"
+#include "RadioConfigResponse.h"
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Config"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::config;
+constexpr auto ok = &ScopedAStatus::ok;
+
+RadioConfig::RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal)
+    : mHal1_1(hidlHal), mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)) {}
+
+config::V1_3::IRadioConfigResponse& RadioConfig::respond() {
+    CHECK(mRadioConfigResponse) << "setResponseFunctions was not called yet";
+    return *mRadioConfigResponse;
+}
+
+ScopedAStatus RadioConfig::getHalDeviceCapabilities(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_3) {
+        mHal1_3->getHalDeviceCapabilities(serial);
+    } else {
+        respond().getHalDeviceCapabilitiesResponse(notSupported(serial), false);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getNumOfLiveModems(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getModemsConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getPhoneCapability(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getPhoneCapability(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getSimSlotsStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getSimSlotsStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) {
+    LOG_CALL << serial;
+    mHal1_1->setModemsConfig(serial, {static_cast<uint8_t>(numOfLiveModems)});
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setPreferredDataModem(int32_t serial, int8_t modemId) {
+    LOG_CALL << serial;
+    mHal1_1->setPreferredDataModem(serial, modemId);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioConfigResponse>& radioConfigResponse,
+        const std::shared_ptr<aidl::IRadioConfigIndication>& radioConfigIndication) {
+    LOG_CALL << radioConfigResponse << ' ' << radioConfigIndication;
+
+    CHECK(radioConfigResponse);
+    CHECK(radioConfigIndication);
+
+    mRadioConfigResponse = sp<RadioConfigResponse>::make(radioConfigResponse);
+    mRadioConfigIndication = sp<RadioConfigIndication>::make(radioConfigIndication);
+    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setSimSlotsMapping(  //
+        int32_t serial, const std::vector<aidl::SlotPortMapping>& slotMap) {
+    LOG_CALL << serial;
+    mHal1_1->setSimSlotsMapping(serial, toHidl(slotMap));
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
new file mode 100644
index 0000000..0320ad7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RadioConfigIndication.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigIndication::RadioConfigIndication(std::shared_ptr<aidl::IRadioConfigIndication> callback)
+    : mCallback(callback) {}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+        V1_0::RadioIndicationType type, const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+    LOG_CALL << type;
+    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    return {};
+}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
+        V1_0::RadioIndicationType type, const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+    LOG_CALL << type;
+    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
new file mode 100644
index 0000000..3d8d971
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigIndication : public config::V1_2::IRadioConfigIndication {
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> mCallback;
+
+    Return<void> simSlotsStatusChanged(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+    Return<void> simSlotsStatusChanged_1_2(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+
+  public:
+    RadioConfigIndication(
+            std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> cb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
new file mode 100644
index 0000000..7066ae4
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RadioConfigResponse.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigResponse::RadioConfigResponse(std::shared_ptr<aidl::IRadioConfigResponse> callback)
+    : mCallback(callback) {}
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+    LOG_CALL << info.serial;
+    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+    LOG_CALL << info.serial;
+    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setSimSlotsMappingResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+        const V1_0::RadioResponseInfo& info, const config::V1_1::PhoneCapability& phoneCapability) {
+    LOG_CALL << info.serial;
+    mCallback->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setPreferredDataModemResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setNumOfLiveModemsResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(
+        const V1_0::RadioResponseInfo& info, const config::V1_1::ModemsConfig& modemsConfig) {
+    LOG_CALL << info.serial;
+    mCallback->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
+    return {};
+};
+
+Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
+        const V1_6::RadioResponseInfo& info, bool modemReducedFeatureSet1) {
+    LOG_CALL << info.serial;
+    mCallback->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
+    return {};
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
new file mode 100644
index 0000000..1461dd2
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/IRadioConfigResponse.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigResponse : public config::V1_3::IRadioConfigResponse {
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> mCallback;
+
+    Return<void> getSimSlotsStatusResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+    Return<void> setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPhoneCapabilityResponse(
+            const V1_0::RadioResponseInfo& info,
+            const config::V1_1::PhoneCapability& phoneCapability) override;
+    Return<void> setPreferredDataModemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setModemsConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getModemsConfigResponse(const V1_0::RadioResponseInfo& info,
+                                         const config::V1_1::ModemsConfig& modemsConfig) override;
+    Return<void> getSimSlotsStatusResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+    Return<void> getHalDeviceCapabilitiesResponse(const V1_6::RadioResponseInfo& info,
+                                                  bool modemReducedFeatureSet1) override;
+
+  public:
+    RadioConfigResponse(
+            std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> callback);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
new file mode 100644
index 0000000..9ba5623
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
+    hidl_vec<uint32_t> out(slotMap.size());
+    for (const auto& el : slotMap) {
+        CHECK_GE(el.portId, 0);
+        CHECK_LT(static_cast<size_t>(el.portId), out.size());
+        out[el.portId] = el.physicalSlotId;
+    }
+    return out;
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
+    return toAidl({sst, ""});
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_2::SimSlotStatus& sst) {
+    const aidl::SimPortInfo portInfo = {
+            .iccId = sst.base.iccid,
+            .logicalSlotId = static_cast<int32_t>(sst.base.logicalSlotId),
+            .portActive = sst.base.slotState == config::V1_0::SlotState::ACTIVE,
+    };
+
+    return {
+            .cardState = static_cast<int32_t>(sst.base.cardState),
+            .atr = sst.base.atr,
+            .eid = sst.eid,
+            .portInfo = {portInfo},
+    };
+}
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info) {
+    return info.modemId;
+}
+
+aidl::PhoneCapability toAidl(const config::V1_1::PhoneCapability& phoneCapability) {
+    return {
+            .maxActiveData = static_cast<int8_t>(phoneCapability.maxActiveData),
+            .maxActiveInternetData = static_cast<int8_t>(phoneCapability.maxActiveInternetData),
+            .isInternetLingeringSupported = phoneCapability.isInternetLingeringSupported,
+            .logicalModemIds = toAidl(phoneCapability.logicalModemList),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
new file mode 100644
index 0000000..b8a0385
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/PhoneCapability.h>
+#include <aidl/android/hardware/radio/config/SimSlotStatus.h>
+#include <aidl/android/hardware/radio/config/SlotPortMapping.h>
+#include <android/hardware/radio/config/1.1/types.h>
+#include <android/hardware/radio/config/1.2/types.h>
+
+namespace android::hardware::radio::compat {
+
+hidl_vec<uint32_t>  //
+toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+
+aidl::android::hardware::radio::config::SimSlotStatus  //
+toAidl(const config::V1_0::SimSlotStatus& sst);
+aidl::android::hardware::radio::config::SimSlotStatus  //
+toAidl(const config::V1_2::SimSlotStatus& sst);
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info);
+
+aidl::android::hardware::radio::config::PhoneCapability  //
+toAidl(const config::V1_1::PhoneCapability& pc);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
new file mode 100644
index 0000000..fdb1273
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioData.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Data"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::data;
+namespace aidlCommon = ::aidl::android::hardware::radio;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioData::allocatePduSessionId(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->allocatePduSessionId(serial);
+    } else {
+        respond().allocatePduSessionIdResponse(notSupported(serial), 0);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::cancelHandover(int32_t serial, int32_t callId) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->cancelHandover(serial, callId);
+    } else {
+        respond().cancelHandoverResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::deactivateDataCall(int32_t serial, int32_t cid,
+                                            aidl::DataRequestReason reason) {
+    LOG_CALL << serial;
+    mHal1_5->deactivateDataCall_1_2(serial, cid, V1_2::DataRequestReason(reason));
+    return ok();
+}
+
+ScopedAStatus RadioData::getDataCallList(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDataCallList(serial);
+    return ok();
+}
+
+ScopedAStatus RadioData::getSlicingConfig(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSlicingConfig(serial);
+    } else {
+        respond().getSlicingConfigResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::releasePduSessionId(int32_t serial, int32_t id) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->releasePduSessionId(serial, id);
+    } else {
+        respond().releasePduSessionIdResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataAllowed(int32_t serial, bool allow) {
+    LOG_CALL << serial;
+    mHal1_5->setDataAllowed(serial, allow);
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataProfile(int32_t serial,
+                                        const std::vector<aidl::DataProfileInfo>& profiles) {
+    LOG_CALL << serial;
+    mHal1_5->setDataProfile_1_5(serial, toHidl(profiles));
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataThrottling(int32_t serial, aidl::DataThrottlingAction dta,
+                                           int64_t completionDurationMs) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setDataThrottling(serial, V1_6::DataThrottlingAction(dta), completionDurationMs);
+    } else {
+        respond().setDataThrottlingResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::setInitialAttachApn(int32_t serial, const aidl::DataProfileInfo& info) {
+    LOG_CALL << serial;
+    mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info));
+    return ok();
+}
+
+ScopedAStatus RadioData::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioDataResponse>& dataResponse,
+        const std::shared_ptr<aidl::IRadioDataIndication>& dataIndication) {
+    LOG_CALL << dataResponse << ' ' << dataIndication;
+
+    CHECK(dataResponse);
+    CHECK(dataIndication);
+
+    mRadioResponse->setResponseFunction(dataResponse);
+    mRadioIndication->setResponseFunction(dataIndication);
+
+    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,
+        const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+    if (mHal1_6) {
+        mHal1_6->setupDataCall_1_6(  //
+                serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+                V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
+                toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
+                toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+    } else {
+        mHal1_5->setupDataCall_1_5(  //
+                serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+                V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::startHandover(int32_t serial, int32_t callId) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->startHandover(serial, callId);
+    } else {
+        respond().startHandoverResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::startKeepalive(int32_t serial, const aidl::KeepaliveRequest& keepalive) {
+    LOG_CALL << serial;
+    mHal1_5->startKeepalive(serial, toHidl(keepalive));
+    return ok();
+}
+
+ScopedAStatus RadioData::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+    LOG_CALL << serial;
+    mHal1_5->stopKeepalive(serial, sessionHandle);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
new file mode 100644
index 0000000..f51d1a8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioDataIndication> dataCb) {
+    CHECK(dataCb);
+    mDataCb = dataCb;
+}
+
+Return<void> RadioIndication::dataCallListChanged(V1_0::RadioIndicationType type,
+                                                  const hidl_vec<V1_0::SetupDataCallResult>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_4(V1_0::RadioIndicationType type,
+                                                      const hidl_vec<V1_4::SetupDataCallResult>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_5(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_5::SetupDataCallResult>& dcList) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_6(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    return {};
+}
+
+Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
+                                              const V1_1::KeepaliveStatus& status) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->keepaliveStatus(toAidl(type), toAidl(status));
+    return {};
+}
+
+Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
+                                      const V1_0::PcoDataInfo& pco) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->pcoData(toAidl(type), toAidl(pco));
+    return {};
+}
+
+Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type,
+                                            const hidl_string& apn) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->unthrottleApn(toAidl(type), apn);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
new file mode 100644
index 0000000..171f692
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioDataResponse> dataCb) {
+    CHECK(dataCb);
+    mDataCb = dataCb;
+}
+
+Return<void> RadioResponse::allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+                                                         int32_t id) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->allocatePduSessionIdResponse(toAidl(info), id);
+    return {};
+}
+
+Return<void> RadioResponse::cancelHandoverResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->cancelHandoverResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->deactivateDataCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::SetupDataCallResult>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_4::SetupDataCallResult>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_5(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_6(
+        const V1_6::RadioResponseInfo& info,
+        const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+                                                     const V1_6::SlicingConfig& slicingConfig) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
+    return {};
+}
+
+Return<void> RadioResponse::releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->releasePduSessionIdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataAllowedResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataProfileResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataProfileResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataThrottlingResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+                                                  const V1_0::SetupDataCallResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                      const V1_4::SetupDataCallResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                      const V1_5::SetupDataCallResult& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                      const V1_6::SetupDataCallResult& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::startHandoverResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->startHandoverResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_1::KeepaliveStatus& status) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->startKeepaliveResponse(toAidl(info), toAidl(status));
+    return {};
+}
+
+Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->stopKeepaliveResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
new file mode 100644
index 0000000..4ff89a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+V1_5::DataProfileInfo toHidl(const aidl::DataProfileInfo& info) {
+    return {
+            .profileId = V1_0::DataProfileId{info.profileId},
+            .apn = info.apn,
+            .protocol = V1_4::PdpProtocolType{info.protocol},
+            .roamingProtocol = V1_4::PdpProtocolType{info.roamingProtocol},
+            .authType = V1_0::ApnAuthType{info.authType},
+            .user = info.user,
+            .password = info.password,
+            .type = V1_0::DataProfileInfoType{info.type},
+            .maxConnsTime = info.maxConnsTime,
+            .maxConns = info.maxConns,
+            .waitTime = info.waitTime,
+            .enabled = info.enabled,
+            .supportedApnTypesBitmap = toHidlBitfield<V1_5::ApnTypes>(info.supportedApnTypesBitmap),
+            .bearerBitmap = toHidlBitfield<V1_4::RadioAccessFamily>(info.bearerBitmap),
+            .mtuV4 = info.mtuV4,
+            .mtuV6 = info.mtuV6,
+            .preferred = info.preferred,
+            .persistent = info.persistent,
+    };
+}
+
+V1_5::LinkAddress toHidl(const aidl::LinkAddress& addr) {
+    return {
+            .address = addr.address,
+            .properties = addr.addressProperties,
+            .deprecationTime = static_cast<uint64_t>(addr.deprecationTime),
+            .expirationTime = static_cast<uint64_t>(addr.expirationTime),
+    };
+}
+
+aidl::SliceInfo toAidl(const V1_6::SliceInfo& info) {
+    return {
+            .sliceServiceType = static_cast<int8_t>(info.sst),
+            .sliceDifferentiator = info.sliceDifferentiator,
+            .mappedHplmnSst = static_cast<int8_t>(info.mappedHplmnSst),
+            .mappedHplmnSd = info.mappedHplmnSD,
+            .status = static_cast<int8_t>(info.status),
+    };
+}
+
+V1_6::SliceInfo toHidl(const aidl::SliceInfo& info) {
+    return {
+            .sst = static_cast<V1_6::SliceServiceType>(info.sliceServiceType),
+            .sliceDifferentiator = info.sliceDifferentiator,
+            .mappedHplmnSst = static_cast<V1_6::SliceServiceType>(info.mappedHplmnSst),
+            .mappedHplmnSD = info.mappedHplmnSd,
+            .status = V1_6::SliceStatus{info.status},
+    };
+}
+
+aidl::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& descr) {
+    return {
+            .dnn = toAidl(descr.dnn),
+            .osAppId = toAidl(descr.osAppId),
+    };
+}
+
+V1_6::TrafficDescriptor toHidl(const aidl::TrafficDescriptor& descr) {
+    return {
+            .dnn = toHidl<V1_6::OptionalDnn>(descr.dnn),
+            .osAppId = toHidl<V1_6::OptionalOsAppId>(descr.osAppId),
+    };
+}
+
+aidl::OsAppId toAidl(const V1_6::OsAppId& appId) {
+    return {
+            .osAppId = appId.osAppId,
+    };
+}
+
+V1_6::OsAppId toHidl(const aidl::OsAppId& appId) {
+    return {
+            .osAppId = appId.osAppId,
+    };
+}
+
+V1_1::KeepaliveRequest toHidl(const aidl::KeepaliveRequest& keep) {
+    return {
+            .type = V1_1::KeepaliveType{keep.type},
+            .sourceAddress = keep.sourceAddress,
+            .sourcePort = keep.sourcePort,
+            .destinationAddress = keep.destinationAddress,
+            .destinationPort = keep.destinationPort,
+            .maxKeepaliveIntervalMillis = keep.maxKeepaliveIntervalMillis,
+            .cid = keep.cid,
+    };
+}
+
+static aidl::QosBandwidth toAidl(const V1_6::QosBandwidth& bw) {
+    return {
+            .maxBitrateKbps = static_cast<int32_t>(bw.maxBitrateKbps),
+            .guaranteedBitrateKbps = static_cast<int32_t>(bw.guaranteedBitrateKbps),
+    };
+}
+
+static aidl::EpsQos toAidl(const V1_6::EpsQos& qos) {
+    return {
+            .qci = qos.qci,
+            .downlink = toAidl(qos.downlink),
+            .uplink = toAidl(qos.uplink),
+    };
+}
+
+static aidl::NrQos toAidl(const V1_6::NrQos& qos) {
+    return {
+            .fiveQi = qos.fiveQi,
+            .downlink = toAidl(qos.downlink),
+            .uplink = toAidl(qos.uplink),
+            .qfi = static_cast<int8_t>(qos.qfi),
+            .averagingWindowMs = qos.averagingWindowMs,
+    };
+}
+
+static std::variant<bool, aidl::EpsQos, aidl::NrQos> toAidl(const V1_6::Qos& qos) {
+    if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::eps) return toAidl(qos.eps());
+    if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::nr) return toAidl(qos.nr());
+    return false;
+}
+
+aidl::SetupDataCallResult toAidl(const V1_5::SetupDataCallResult& res) {
+    return {
+            .cause = aidl::DataCallFailCause(res.cause),
+            .suggestedRetryTime = res.suggestedRetryTime,
+            .cid = res.cid,
+            .active = static_cast<int32_t>(res.active),
+            .type = aidl::PdpProtocolType(res.type),
+            .ifname = res.ifname,
+            .addresses = toAidl(res.addresses),
+            .dnses = toAidl(res.dnses),
+            .gateways = toAidl(res.gateways),
+            .pcscf = toAidl(res.pcscf),
+            .mtuV4 = res.mtuV4,
+            .mtuV6 = res.mtuV6,
+    };
+}
+
+aidl::SetupDataCallResult toAidl(const V1_6::SetupDataCallResult& res) {
+    return {
+            .cause = aidl::DataCallFailCause(res.cause),
+            .suggestedRetryTime = res.suggestedRetryTime,
+            .cid = res.cid,
+            .active = static_cast<int32_t>(res.active),
+            .type = aidl::PdpProtocolType(res.type),
+            .ifname = res.ifname,
+            .addresses = toAidl(res.addresses),
+            .dnses = toAidl(res.dnses),
+            .gateways = toAidl(res.gateways),
+            .pcscf = toAidl(res.pcscf),
+            .mtuV4 = res.mtuV4,
+            .mtuV6 = res.mtuV6,
+            .defaultQos = toAidl(res.defaultQos),
+            .qosSessions = toAidl(res.qosSessions),
+            .handoverFailureMode = static_cast<int8_t>(res.handoverFailureMode),
+            .pduSessionId = res.pduSessionId,
+            .sliceInfo = toAidl(res.sliceInfo),
+            .trafficDescriptors = toAidl(res.trafficDescriptors),
+    };
+}
+
+aidl::LinkAddress toAidl(const V1_5::LinkAddress& addr) {
+    return {
+            .address = addr.address,
+            .addressProperties = addr.properties,
+            .deprecationTime = static_cast<int64_t>(addr.deprecationTime),
+            .expirationTime = static_cast<int64_t>(addr.expirationTime),
+    };
+}
+
+aidl::QosSession toAidl(const V1_6::QosSession& sess) {
+    return {
+            .qosSessionId = sess.qosSessionId,
+            .qos = toAidl(sess.qos),
+            .qosFilters = toAidl(sess.qosFilters),
+    };
+}
+
+static aidl::PortRange toAidl(const V1_6::PortRange& range) {
+    return {
+            .start = range.start,
+            .end = range.end,
+    };
+}
+
+static std::optional<aidl::PortRange> toAidl(const V1_6::MaybePort& opt) {
+    if (opt.getDiscriminator() == V1_6::MaybePort::hidl_discriminator::noinit) return std::nullopt;
+    return toAidl(opt.range());  // can't use MaybeX template - this field is not named "value"
+}
+
+aidl::QosFilter toAidl(const V1_6::QosFilter& filter) {
+    return {
+            .localAddresses = toAidl(filter.localAddresses),
+            .remoteAddresses = toAidl(filter.remoteAddresses),
+            .localPort = toAidl(filter.localPort),
+            .remotePort = toAidl(filter.remotePort),
+            .protocol = static_cast<int8_t>(filter.protocol),
+            .tos = toAidlVariant(filter.tos),
+            .flowLabel = toAidlVariant(filter.flowLabel),
+            .spi = toAidlVariant(filter.spi),
+            .direction = static_cast<int8_t>(filter.direction),
+            .precedence = filter.precedence,
+    };
+}
+
+aidl::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status) {
+    return {
+            .sessionHandle = status.sessionHandle,
+            .code = static_cast<int32_t>(status.code),
+    };
+}
+
+aidl::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info) {
+    return {
+            .cid = info.cid,
+            .bearerProto = info.bearerProto,
+            .pcoId = info.pcoId,
+            .contents = info.contents,
+    };
+}
+
+aidl::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg) {
+    return {
+            .urspRules = toAidl(cfg.urspRules),
+            .sliceInfo = toAidl(cfg.sliceInfo),
+    };
+}
+
+aidl::UrspRule toAidl(const V1_6::UrspRule& rule) {
+    return {
+            .precedence = rule.precedence,
+            .trafficDescriptors = toAidl(rule.trafficDescriptors),
+            .routeSelectionDescriptor = toAidl(rule.routeSelectionDescriptor),
+    };
+}
+
+static int8_t toAidl(const V1_6::OptionalSscMode& opt) {
+    if (opt.getDiscriminator() == V1_6::OptionalSscMode::hidl_discriminator::noinit) {
+        return aidl::RouteSelectionDescriptor::SSC_MODE_UNKNOWN;
+    }
+    return static_cast<int8_t>(opt.value());
+}
+
+static aidl::PdpProtocolType toAidl(const V1_6::OptionalPdpProtocolType& opt) {
+    using discriminator = V1_6::OptionalPdpProtocolType::hidl_discriminator;
+    if (opt.getDiscriminator() == discriminator::noinit) return aidl::PdpProtocolType::UNKNOWN;
+    return aidl::PdpProtocolType(opt.value());
+}
+
+aidl::RouteSelectionDescriptor toAidl(const V1_6::RouteSelectionDescriptor& descr) {
+    return {
+            .precedence = static_cast<int8_t>(descr.precedence),
+            .sessionType = toAidl(descr.sessionType),
+            .sscMode = toAidl(descr.sscMode),
+            .sliceInfo = toAidl(descr.sliceInfo),
+            .dnn = toAidl(descr.dnn),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.h b/radio/aidl/compat/libradiocompat/data/structs.h
new file mode 100644
index 0000000..60fad57
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+#include <aidl/android/hardware/radio/data/KeepaliveRequest.h>
+#include <aidl/android/hardware/radio/data/KeepaliveStatus.h>
+#include <aidl/android/hardware/radio/data/LinkAddress.h>
+#include <aidl/android/hardware/radio/data/OsAppId.h>
+#include <aidl/android/hardware/radio/data/PcoDataInfo.h>
+#include <aidl/android/hardware/radio/data/RouteSelectionDescriptor.h>
+#include <aidl/android/hardware/radio/data/SetupDataCallResult.h>
+#include <aidl/android/hardware/radio/data/SliceInfo.h>
+#include <aidl/android/hardware/radio/data/SlicingConfig.h>
+#include <aidl/android/hardware/radio/data/TrafficDescriptor.h>
+#include <aidl/android/hardware/radio/data/UrspRule.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_5::DataProfileInfo toHidl(const ::aidl::android::hardware::radio::data::DataProfileInfo& info);
+
+V1_5::LinkAddress toHidl(const ::aidl::android::hardware::radio::data::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::SliceInfo toAidl(const V1_6::SliceInfo& info);
+V1_6::SliceInfo toHidl(const ::aidl::android::hardware::radio::data::SliceInfo& info);
+
+::aidl::android::hardware::radio::data::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& td);
+V1_6::TrafficDescriptor toHidl(const ::aidl::android::hardware::radio::data::TrafficDescriptor& td);
+
+V1_1::KeepaliveRequest toHidl(const ::aidl::android::hardware::radio::data::KeepaliveRequest& keep);
+
+::aidl::android::hardware::radio::data::OsAppId toAidl(const V1_6::OsAppId& appId);
+V1_6::OsAppId toHidl(const ::aidl::android::hardware::radio::data::OsAppId& appId);
+
+::aidl::android::hardware::radio::data::SetupDataCallResult  //
+toAidl(const V1_5::SetupDataCallResult& res);
+::aidl::android::hardware::radio::data::SetupDataCallResult  //
+toAidl(const V1_6::SetupDataCallResult& res);
+
+::aidl::android::hardware::radio::data::LinkAddress toAidl(const V1_5::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::QosSession toAidl(const V1_6::QosSession& session);
+
+::aidl::android::hardware::radio::data::QosFilter toAidl(const V1_6::QosFilter& filter);
+
+::aidl::android::hardware::radio::data::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status);
+
+::aidl::android::hardware::radio::data::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info);
+
+::aidl::android::hardware::radio::data::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg);
+
+::aidl::android::hardware::radio::data::UrspRule toAidl(const V1_6::UrspRule& rule);
+
+::aidl::android::hardware::radio::data::RouteSelectionDescriptor  //
+toAidl(const V1_6::RouteSelectionDescriptor& descr);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/debug.h b/radio/aidl/compat/libradiocompat/debug.h
new file mode 100644
index 0000000..4158059
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/debug.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace debug {
+
+static constexpr bool kSuperVerbose = true;
+
+#define LOG_CALL \
+    if constexpr (debug::kSuperVerbose) LOG(VERBOSE) << (RADIO_MODULE ".") << __func__ << ' '
+
+#define CHECK_CB(field)                     \
+    if (!field) {                           \
+        LOG(WARNING) << "Callback not set"; \
+        return {};                          \
+    }
+
+}  // namespace debug
+
+inline std::ostream& operator<<(std::ostream& os, const V1_0::RadioIndicationType& type) {
+    return os << static_cast<int>(type);
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
new file mode 100644
index 0000000..a412c34
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+#include <android/hardware/radio/1.6/IRadio.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioCompatBase {
+  protected:
+    sp<V1_5::IRadio> mHal1_5;
+    sp<V1_6::IRadio> mHal1_6;
+
+    sp<RadioResponse> mRadioResponse;
+    sp<RadioIndication> mRadioIndication;
+
+    V1_6::IRadioResponse& respond();
+
+  public:
+    RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+                    sp<RadioIndication> radioIndication);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
new file mode 100644
index 0000000..31ad207
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/BnRadioConfig.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * HAL translator from HIDL IRadioConfig to AIDL IRadioConfig.
+ *
+ * This class wraps existing HIDL implementation (either a binder stub or real
+ * class implementing the HAL) and implements AIDL HAL. It's up to the caller to
+ * fetch source implementation and publish resulting HAL instance.
+ */
+class RadioConfig : public aidl::android::hardware::radio::config::BnRadioConfig {
+    sp<config::V1_1::IRadioConfig> mHal1_1;
+    sp<config::V1_3::IRadioConfig> mHal1_3;
+
+    sp<config::V1_3::IRadioConfigResponse> mRadioConfigResponse;
+    sp<config::V1_2::IRadioConfigIndication> mRadioConfigIndication;
+
+    ::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
+    ::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
+    ::ndk::ScopedAStatus getPhoneCapability(int32_t serial) override;
+    ::ndk::ScopedAStatus getSimSlotsStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) override;
+    ::ndk::ScopedAStatus setPreferredDataModem(int32_t serial, int8_t modemId) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse>&
+                    radioConfigResponse,
+            const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication>&
+                    radioConfigIndication) override;
+    ::ndk::ScopedAStatus setSimSlotsMapping(
+            int32_t serial,
+            const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
+            override;
+
+    config::V1_3::IRadioConfigResponse& respond();
+
+  public:
+    /**
+     * Constructs AIDL IRadioConfig instance wrapping existing HIDL IRadioConfig instance.
+     *
+     * \param hidlHal existing HIDL IRadioConfig HAL instance
+     */
+    RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
new file mode 100644
index 0000000..900a669
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/data/BnRadioData.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioData : public RadioCompatBase, public aidl::android::hardware::radio::data::BnRadioData {
+    ::ndk::ScopedAStatus allocatePduSessionId(int32_t serial) override;
+    ::ndk::ScopedAStatus cancelHandover(int32_t serial, int32_t callId) override;
+    ::ndk::ScopedAStatus deactivateDataCall(
+            int32_t serial, int32_t cid,
+            ::aidl::android::hardware::radio::data::DataRequestReason reason) override;
+    ::ndk::ScopedAStatus getDataCallList(int32_t serial) override;
+    ::ndk::ScopedAStatus getSlicingConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus releasePduSessionId(int32_t serial, int32_t id) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus setDataAllowed(int32_t serial, bool allow) override;
+    ::ndk::ScopedAStatus setDataProfile(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::data::DataProfileInfo>& profiles)
+            override;
+    ::ndk::ScopedAStatus setDataThrottling(
+            int32_t serial,
+            ::aidl::android::hardware::radio::data::DataThrottlingAction dataThrottlingAction,
+            int64_t completionDurationMillis) override;
+    ::ndk::ScopedAStatus setInitialAttachApn(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::data::DataProfileInfo& dpInfo) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse>&
+                    radioDataResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication>&
+                    radioDataIndication) override;
+    ::ndk::ScopedAStatus setupDataCall(
+            int32_t serial, ::aidl::android::hardware::radio::AccessNetwork accessNetwork,
+            const ::aidl::android::hardware::radio::data::DataProfileInfo& dataProfileInfo,
+            bool roamingAllowed, ::aidl::android::hardware::radio::data::DataRequestReason reason,
+            const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
+            const std::vector<std::string>& dnses, int32_t pduSessionId,
+            const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
+            const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
+            bool matchAllRuleAllowed) override;
+    ::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
+    ::ndk::ScopedAStatus startKeepalive(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::data::KeepaliveRequest& keepalive) override;
+    ::ndk::ScopedAStatus stopKeepalive(int32_t serial, int32_t sessionHandle) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
new file mode 100644
index 0000000..20e0973
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
+#include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
+#include <aidl/android/hardware/radio/network/IRadioNetworkIndication.h>
+#include <aidl/android/hardware/radio/sim/IRadioSimIndication.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceIndication.h>
+#include <android/hardware/radio/1.6/IRadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioIndication : public V1_6::IRadioIndication {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+            mMessagingCb;
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> mModemCb;
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> mNetworkCb;
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> mSimCb;
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> mVoiceCb;
+
+    // IRadioIndication @ 1.0
+    Return<void> radioStateChanged(V1_0::RadioIndicationType type,
+                                   V1_0::RadioState radioState) override;
+    Return<void> callStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> networkStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) override;
+    Return<void> newSmsStatusReport(V1_0::RadioIndicationType type,
+                                    const hidl_vec<uint8_t>& pdu) override;
+    Return<void> newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) override;
+    Return<void> onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                        const hidl_string& msg) override;
+    Return<void> nitzTimeReceived(V1_0::RadioIndicationType type, const hidl_string& nitzTime,
+                                  uint64_t receivedTime) override;
+    Return<void> currentSignalStrength(V1_0::RadioIndicationType type,
+                                       const V1_0::SignalStrength& signalStrength) override;
+    Return<void> dataCallListChanged(V1_0::RadioIndicationType type,
+                                     const hidl_vec<V1_0::SetupDataCallResult>& dcList) override;
+    Return<void> suppSvcNotify(V1_0::RadioIndicationType type,
+                               const V1_0::SuppSvcNotification& suppSvc) override;
+    Return<void> stkSessionEnd(V1_0::RadioIndicationType type) override;
+    Return<void> stkProactiveCommand(V1_0::RadioIndicationType type,
+                                     const hidl_string& cmd) override;
+    Return<void> stkEventNotify(V1_0::RadioIndicationType type, const hidl_string& cmd) override;
+    Return<void> stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) override;
+    Return<void> simSmsStorageFull(V1_0::RadioIndicationType type) override;
+    Return<void> simRefresh(V1_0::RadioIndicationType type,
+                            const V1_0::SimRefreshResult& refreshResult) override;
+    Return<void> callRing(V1_0::RadioIndicationType type, bool isGsm,
+                          const V1_0::CdmaSignalInfoRecord& record) override;
+    Return<void> simStatusChanged(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaNewSms(V1_0::RadioIndicationType type,
+                            const V1_0::CdmaSmsMessage& msg) override;
+    Return<void> newBroadcastSms(V1_0::RadioIndicationType type,
+                                 const hidl_vec<uint8_t>& data) override;
+    Return<void> cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) override;
+    Return<void> restrictedStateChanged(V1_0::RadioIndicationType type,
+                                        V1_0::PhoneRestrictedState state) override;
+    Return<void> enterEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaCallWaiting(V1_0::RadioIndicationType type,
+                                 const V1_0::CdmaCallWaiting& callWaitingRecord) override;
+    Return<void> cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+                                        V1_0::CdmaOtaProvisionStatus status) override;
+    Return<void> cdmaInfoRec(V1_0::RadioIndicationType type,
+                             const V1_0::CdmaInformationRecords& records) override;
+    Return<void> indicateRingbackTone(V1_0::RadioIndicationType type, bool start) override;
+    Return<void> resendIncallMute(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaSubscriptionSourceChanged(V1_0::RadioIndicationType type,
+                                               V1_0::CdmaSubscriptionSource cdmaSource) override;
+    Return<void> cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) override;
+    Return<void> exitEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+    Return<void> rilConnected(V1_0::RadioIndicationType type) override;
+    Return<void> voiceRadioTechChanged(V1_0::RadioIndicationType type,
+                                       V1_0::RadioTechnology rat) override;
+    Return<void> cellInfoList(V1_0::RadioIndicationType type,
+                              const hidl_vec<V1_0::CellInfo>& records) override;
+    Return<void> imsNetworkStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> subscriptionStatusChanged(V1_0::RadioIndicationType type, bool activate) override;
+    Return<void> srvccStateNotify(V1_0::RadioIndicationType type, V1_0::SrvccState state) override;
+    Return<void> hardwareConfigChanged(V1_0::RadioIndicationType type,
+                                       const hidl_vec<V1_0::HardwareConfig>& configs) override;
+    Return<void> radioCapabilityIndication(V1_0::RadioIndicationType type,
+                                           const V1_0::RadioCapability& rc) override;
+    Return<void> onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+                                                  const V1_0::StkCcUnsolSsResult& ss) override;
+    Return<void> stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+                                           const hidl_string& alpha) override;
+    Return<void> lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo& lce) override;
+    Return<void> pcoData(V1_0::RadioIndicationType type, const V1_0::PcoDataInfo& pco) override;
+    Return<void> modemReset(V1_0::RadioIndicationType type, const hidl_string& reason) override;
+
+    // IRadioIndication @ 1.1
+    Return<void> carrierInfoForImsiEncryption(V1_0::RadioIndicationType info) override;
+    Return<void> networkScanResult(V1_0::RadioIndicationType type,
+                                   const V1_1::NetworkScanResult& result) override;
+    Return<void> keepaliveStatus(V1_0::RadioIndicationType type,
+                                 const V1_1::KeepaliveStatus& status) override;
+
+    // IRadioIndication @ 1.2
+    Return<void> networkScanResult_1_2(V1_0::RadioIndicationType type,
+                                       const V1_2::NetworkScanResult& result) override;
+    Return<void> cellInfoList_1_2(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_2::CellInfo>& records) override;
+    Return<void> currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+                                             const V1_2::LinkCapacityEstimate& lce) override;
+    Return<void> currentPhysicalChannelConfigs(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_2::PhysicalChannelConfig>& configs) override;
+    Return<void> currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+                                           const V1_2::SignalStrength& signalStrength) override;
+
+    // IRadioIndication @ 1.4
+    Return<void> currentEmergencyNumberList(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::EmergencyNumber>& emergencyNumberList) override;
+    Return<void> cellInfoList_1_4(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_4::CellInfo>& records) override;
+    Return<void> networkScanResult_1_4(V1_0::RadioIndicationType type,
+                                       const V1_4::NetworkScanResult& result) override;
+    Return<void> currentPhysicalChannelConfigs_1_4(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::PhysicalChannelConfig>& configs) override;
+    Return<void> dataCallListChanged_1_4(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::SetupDataCallResult>& dcList) override;
+    Return<void> currentSignalStrength_1_4(V1_0::RadioIndicationType type,
+                                           const V1_4::SignalStrength& signalStrength) override;
+
+    // IRadioIndication @ 1.5
+    Return<void> uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+                                                   bool enabled) override;
+    Return<void> registrationFailed(  //
+            V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+            const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+            int32_t additionalCauseCode) override;
+    Return<void> barringInfoChanged(  //
+            V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+            const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+    Return<void> cellInfoList_1_5(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_5::CellInfo>& records) override;
+    Return<void> networkScanResult_1_5(V1_0::RadioIndicationType type,
+                                       const V1_5::NetworkScanResult& result) override;
+    Return<void> dataCallListChanged_1_5(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_5::SetupDataCallResult>& dcList) override;
+
+    // IRadioIndication @ 1.6
+    Return<void> dataCallListChanged_1_6(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_6::SetupDataCallResult>& dcList) override;
+    Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override;
+    Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type,
+                                                 const V1_6::LinkCapacityEstimate& lce) override;
+    Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type,
+                                           const V1_6::SignalStrength& signalStrength) override;
+    Return<void> cellInfoList_1_6(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_6::CellInfo>& records) override;
+    Return<void> networkScanResult_1_6(V1_0::RadioIndicationType type,
+                                       const V1_6::NetworkScanResult& result) override;
+    Return<void> currentPhysicalChannelConfigs_1_6(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_6::PhysicalChannelConfig>& configs) override;
+    Return<void> simPhonebookChanged(V1_0::RadioIndicationType type) override;
+    Return<void> simPhonebookRecordsReceived(
+            V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+            const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
+
+  public:
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+                    radioMessagingIndication);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> modmCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> ni);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
new file mode 100644
index 0000000..0cd3381
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/messaging/BnRadioMessaging.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioMessaging : public RadioCompatBase,
+                       public aidl::android::hardware::radio::messaging::BnRadioMessaging {
+    ::ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+                                                          const std::string& ackPdu) override;
+    ::ndk::ScopedAStatus acknowledgeLastIncomingCdmaSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& smsAck) override;
+    ::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;
+    ::ndk::ScopedAStatus getGsmBroadcastConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus getSmscAddress(int32_t serial) override;
+    ::ndk::ScopedAStatus reportSmsMemoryStatus(int32_t serial, bool available) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendCdmaSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+    ::ndk::ScopedAStatus sendCdmaSmsExpectMore(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+    ::ndk::ScopedAStatus sendImsSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& message) override;
+    ::ndk::ScopedAStatus sendSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
+    ::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,
+            const std::vector<
+                    ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo>&
+                    configInfo) override;
+    ::ndk::ScopedAStatus setGsmBroadcastActivation(int32_t serial, bool activate) override;
+    ::ndk::ScopedAStatus setGsmBroadcastConfig(
+            int32_t serial,
+            const std::vector<
+                    ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo>&
+                    configInfo) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>&
+                    radioMessagingResponse,
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>&
+                    radioMessagingIndication) override;
+    ::ndk::ScopedAStatus setSmscAddress(int32_t serial, const std::string& smsc) override;
+    ::ndk::ScopedAStatus writeSmsToRuim(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& cdmaSms) override;
+    ::ndk::ScopedAStatus writeSmsToSim(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& smsWriteArgs) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
new file mode 100644
index 0000000..666ff47
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/modem/BnRadioModem.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioModem : public RadioCompatBase,
+                   public aidl::android::hardware::radio::modem::BnRadioModem {
+    ::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
+    ::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
+    ::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
+    ::ndk::ScopedAStatus getHardwareConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus getModemActivityInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus getModemStackStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus getRadioCapability(int32_t serial) override;
+    ::ndk::ScopedAStatus nvReadItem(
+            int32_t serial, ::aidl::android::hardware::radio::modem::NvItem itemId) override;
+    ::ndk::ScopedAStatus nvResetConfig(
+            int32_t serial, ::aidl::android::hardware::radio::modem::ResetNvType type) override;
+    ::ndk::ScopedAStatus nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) override;
+    ::ndk::ScopedAStatus nvWriteItem(
+            int32_t serial, const ::aidl::android::hardware::radio::modem::NvWriteItem& i) override;
+    ::ndk::ScopedAStatus requestShutdown(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendDeviceState(
+            int32_t serial, ::aidl::android::hardware::radio::modem::DeviceStateType stateType,
+            bool state) override;
+    ::ndk::ScopedAStatus setRadioCapability(
+            int32_t s, const ::aidl::android::hardware::radio::modem::RadioCapability& rc) override;
+    ::ndk::ScopedAStatus setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+                                       bool preferredForEmergencyCall) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse>&
+                    radioModemResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication>&
+                    radioModemIndication) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
new file mode 100644
index 0000000..c776fd1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/network/BnRadioNetwork.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioNetwork : public RadioCompatBase,
+                     public aidl::android::hardware::radio::network::BnRadioNetwork {
+    ::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
+    ::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
+    ::ndk::ScopedAStatus getAvailableNetworks(int32_t serial) override;
+    ::ndk::ScopedAStatus getBarringInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaRoamingPreference(int32_t serial) override;
+    ::ndk::ScopedAStatus getCellInfoList(int32_t serial) override;
+    ::ndk::ScopedAStatus getDataRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus getImsRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus getNetworkSelectionMode(int32_t serial) override;
+    ::ndk::ScopedAStatus getOperator(int32_t serial) override;
+    ::ndk::ScopedAStatus getSignalStrength(int32_t serial) override;
+    ::ndk::ScopedAStatus getSystemSelectionChannels(int32_t serial) override;
+    ::ndk::ScopedAStatus getVoiceRadioTechnology(int32_t serial) override;
+    ::ndk::ScopedAStatus getVoiceRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus isNrDualConnectivityEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(
+            int32_t serial,
+            ::aidl::android::hardware::radio::RadioAccessFamily networkTypeBitmap) override;
+    ::ndk::ScopedAStatus setBandMode(
+            int32_t serial, ::aidl::android::hardware::radio::network::RadioBandMode mode) override;
+    ::ndk::ScopedAStatus setBarringPassword(int32_t serial, const std::string& facility,
+                                            const std::string& oldPassword,
+                                            const std::string& newPassword) override;
+    ::ndk::ScopedAStatus setCdmaRoamingPreference(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::CdmaRoamingType type) override;
+    ::ndk::ScopedAStatus setCellInfoListRate(int32_t serial, int32_t rate) override;
+    ::ndk::ScopedAStatus setIndicationFilter(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::IndicationFilter indicationFilter) override;
+    ::ndk::ScopedAStatus setLinkCapacityReportingCriteria(
+            int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps,
+            int32_t hysteresisUlKbps, const std::vector<int32_t>& thresholdsDownlinkKbps,
+            const std::vector<int32_t>& thresholdsUplinkKbps,
+            ::aidl::android::hardware::radio::AccessNetwork accessNetwork) override;
+    ::ndk::ScopedAStatus setLocationUpdates(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setNetworkSelectionModeAutomatic(int32_t serial) override;
+    ::ndk::ScopedAStatus setNetworkSelectionModeManual(
+            int32_t serial, const std::string& operatorNumeric,
+            ::aidl::android::hardware::radio::AccessNetwork ran) override;
+    ::ndk::ScopedAStatus setNrDualConnectivityState(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::NrDualConnectivityState nrSt) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse>&
+                    radioNetworkResponse,
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::network::IRadioNetworkIndication>&
+                    radioNetworkIndication) override;
+    ::ndk::ScopedAStatus setSignalStrengthReportingCriteria(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::network::SignalThresholdInfo>&
+                    signalThresholdInfos) override;
+    ::ndk::ScopedAStatus setSuppServiceNotifications(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setSystemSelectionChannels(
+            int32_t serial, bool specifyChannels,
+            const std::vector<::aidl::android::hardware::radio::network::RadioAccessSpecifier>&
+                    specifiers) override;
+    ::ndk::ScopedAStatus startNetworkScan(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::network::NetworkScanRequest& request) override;
+    ::ndk::ScopedAStatus stopNetworkScan(int32_t serial) override;
+    ::ndk::ScopedAStatus supplyNetworkDepersonalization(int32_t serial,
+                                                        const std::string& netPin) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
new file mode 100644
index 0000000..5db963f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
+#include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
+#include <aidl/android/hardware/radio/network/IRadioNetworkResponse.h>
+#include <aidl/android/hardware/radio/sim/IRadioSimResponse.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceResponse.h>
+#include <android/hardware/radio/1.6/IRadioResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioResponse : public V1_6::IRadioResponse {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+            mMessagingCb;
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> mModemCb;
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> mNetworkCb;
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> mSimCb;
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> mVoiceCb;
+
+    // IRadioResponse @ 1.0
+    Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+                                          const V1_0::CardStatus& cardStatus) override;
+    Return<void> supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> supplyNetworkDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) override;
+    Return<void> getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+                                         const hidl_vec<V1_0::Call>& calls) override;
+    Return<void> dialResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+                                       const hidl_string& imsi) override;
+    Return<void> hangupConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> hangupForegroundResumeBackgroundResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> switchWaitingOrHoldingAndActiveResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> conferenceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> rejectCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getLastCallFailCauseResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::LastCallFailCauseInfo& failCauseinfo) override;
+    Return<void> getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+                                           const V1_0::SignalStrength& sigStrength) override;
+    Return<void> getVoiceRegistrationStateResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::VoiceRegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::DataRegStateResult& dataRegResponse) override;
+    Return<void> getOperatorResponse(const V1_0::RadioResponseInfo& info,
+                                     const hidl_string& longName, const hidl_string& shortName,
+                                     const hidl_string& numeric) override;
+    Return<void> setRadioPowerResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendSmsResponse(const V1_0::RadioResponseInfo& info,
+                                 const V1_0::SendSmsResult& sms) override;
+    Return<void> sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                           const V1_0::SendSmsResult& sms) override;
+    Return<void> setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+                                       const V1_0::SetupDataCallResult& dcResponse) override;
+    Return<void> iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::IccIoResult& iccIo) override;
+    Return<void> sendUssdResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+                                 int32_t m) override;
+    Return<void> setClirResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCallForwardStatusResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::CallForwardInfo>& callForwardInfos) override;
+    Return<void> setCallForwardResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+                                        int32_t serviceClass) override;
+    Return<void> setCallWaitingResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> acknowledgeLastIncomingGsmSmsResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> acceptCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t response) override;
+    Return<void> setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t retry) override;
+    Return<void> setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+                                                 bool manual) override;
+    Return<void> setNetworkSelectionModeAutomaticResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setNetworkSelectionModeManualResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAvailableNetworksResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::OperatorInfo>& networkInfos) override;
+    Return<void> startDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> stopDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+                                            const hidl_string& version) override;
+    Return<void> separateConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setMuteResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) override;
+    Return<void> getClipResponse(const V1_0::RadioResponseInfo& info,
+                                 V1_0::ClipStatus status) override;
+    Return<void> getDataCallListResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::SetupDataCallResult>& dcResponse) override;
+    Return<void> setSuppServiceNotificationsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> writeSmsToSimResponse(const V1_0::RadioResponseInfo& info, int32_t index) override;
+    Return<void> deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setBandModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAvailableBandModesResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::RadioBandMode>& bandModes) override;
+    Return<void> sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+                                      const hidl_string& commandResponse) override;
+    Return<void> sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> handleStkCallSetupRequestFromSimResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+                                                 V1_0::PreferredNetworkType nwType) override;
+    Return<void> getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+                                            const hidl_vec<V1_0::NeighboringCell>& cells) override;
+    Return<void> setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+                                                  V1_0::CdmaRoamingType type) override;
+    Return<void> setTTYModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+                                    V1_0::TtyMode mode) override;
+    Return<void> setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+                                                  bool enable) override;
+    Return<void> sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::SendSmsResult& sms) override;
+    Return<void> acknowledgeLastIncomingCdmaSmsResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getGsmBroadcastConfigResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configs) override;
+    Return<void> setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaBroadcastConfigResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) override;
+    Return<void> setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCDMASubscriptionResponse(  //
+            const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+            const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) override;
+    Return<void> writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+                                        uint32_t index) override;
+    Return<void> deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getDeviceIdentityResponse(  //
+            const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+            const hidl_string& esn, const hidl_string& meid) override;
+    Return<void> exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+                                        const hidl_string& smsc) override;
+    Return<void> setSmscAddressResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+                                                   V1_0::CdmaSubscriptionSource source) override;
+    Return<void> requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                   const hidl_string& response) override;
+    Return<void> acknowledgeIncomingGsmSmsWithPduResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::IccIoResult& iccIo) override;
+    Return<void> getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+                                                 V1_0::RadioTechnology rat) override;
+    Return<void> getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+                                         const hidl_vec<V1_0::CellInfo>& cellInfo) override;
+    Return<void> setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getImsRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                 bool isRegistered,
+                                                 V1_0::RadioTechnologyFamily ratFamily) override;
+    Return<void> sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+                                    const V1_0::SendSmsResult& sms) override;
+    Return<void> iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::IccIoResult& result) override;
+    Return<void> iccOpenLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t channelId,
+                                               const hidl_vec<int8_t>& selectResponse) override;
+    Return<void> iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> iccTransmitApduLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::IccIoResult& result) override;
+    Return<void> nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+                                    const hidl_string& result) override;
+    Return<void> nvWriteItemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> nvResetConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setDataAllowedResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getHardwareConfigResponse(const V1_0::RadioResponseInfo& info,
+                                           const hidl_vec<V1_0::HardwareConfig>& config) override;
+    Return<void> requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::IccIoResult& result) override;
+    Return<void> setDataProfileResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> requestShutdownResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::RadioCapability& rc) override;
+    Return<void> setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::RadioCapability& rc) override;
+    Return<void> startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                         const V1_0::LceStatusInfo& statusInfo) override;
+    Return<void> stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_0::LceStatusInfo& statusInfo) override;
+    Return<void> pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::LceDataInfo& lceInfo) override;
+    Return<void> getModemActivityInfoResponse(const V1_0::RadioResponseInfo& info,
+                                              const V1_0::ActivityStatsInfo& activityInfo) override;
+    Return<void> setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t numAllowed) override;
+    Return<void> getAllowedCarriersResponse(const V1_0::RadioResponseInfo& info, bool allAllowed,
+                                            const V1_0::CarrierRestrictions& carriers) override;
+    Return<void> sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> acknowledgeRequest(int32_t serial) override;
+
+    // IRadioResponse @ 1.1
+    Return<void> setCarrierInfoForImsiEncryptionResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_1::KeepaliveStatus& status) override;
+    Return<void> stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) override;
+
+    // IRadioResponse @ 1.2
+    Return<void> getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_2::CellInfo>& cellInfo) override;
+    Return<void> getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                              const V1_2::CardStatus& cardStatus) override;
+    Return<void> setSignalStrengthReportingCriteriaResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setLinkCapacityReportingCriteriaResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_2::Call>& calls) override;
+    Return<void> getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                               const V1_2::SignalStrength& signalStrength) override;
+    Return<void> getVoiceRegistrationStateResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const V1_2::VoiceRegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const V1_2::DataRegStateResult& dataRegResponse) override;
+
+    // IRadioResponse @ 1.3
+    Return<void> setSystemSelectionChannelsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> enableModemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+                                             bool isEnabled) override;
+
+    // IRadioResponse @ 1.4
+    Return<void> emergencyDialResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_4::CellInfo>& cellInfo) override;
+    Return<void> getDataRegistrationStateResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const V1_4::DataRegStateResult& dataRegResponse) override;
+    Return<void> getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                              const V1_4::CardStatus& cardStatus) override;
+    Return<void> getPreferredNetworkTypeBitmapResponse(
+            const V1_0::RadioResponseInfo& info,
+            hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+    Return<void> setPreferredNetworkTypeBitmapResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getDataCallListResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_4::SetupDataCallResult>& dcResponse) override;
+    Return<void> setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                           const V1_4::SetupDataCallResult& dcResponse) override;
+    Return<void> setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAllowedCarriersResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const V1_4::CarrierRestrictionsWithPriority& carriers,
+            V1_4::SimLockMultiSimPolicy multiSimPolicy) override;
+    Return<void> getSignalStrengthResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                               const V1_4::SignalStrength& signalStrength) override;
+
+    // IRadioResponse @ 1.5
+    Return<void> setSignalStrengthReportingCriteriaResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setLinkCapacityReportingCriteriaResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+                                                    bool enabled) override;
+    Return<void> setSystemSelectionChannelsResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                           const V1_5::SetupDataCallResult& dcResponse) override;
+    Return<void> getDataCallListResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) override;
+    Return<void> setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getBarringInfoResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_5::CellIdentity& cellIdentity,
+                                        const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+    Return<void> getVoiceRegistrationStateResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const V1_5::RegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const V1_5::RegStateResult& dataRegResponse) override;
+    Return<void> getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_5::CellInfo>& cellInfo) override;
+    Return<void> setNetworkSelectionModeManualResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) override;
+    Return<void> supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                    V1_5::PersoSubstate persoType,
+                                                    int32_t remainingRetries) override;
+    Return<void> getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                              const V1_5::CardStatus& cardStatus) override;
+
+    // IRadioResponse @ 1.6
+    Return<void> setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                           const V1_6::SetupDataCallResult& dcResponse) override;
+    Return<void> getDataCallListResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) override;
+    Return<void> sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                     const V1_0::SendSmsResult& sms) override;
+    Return<void> sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) override;
+    Return<void> sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                         const V1_0::SendSmsResult& sms) override;
+    Return<void> sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                   const V1_0::SendSmsResult& sms) override;
+    Return<void> setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setNrDualConnectivityStateResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+                                                     bool isEnabled) override;
+    Return<void> allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+                                              int32_t id) override;
+    Return<void> releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> startHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> cancelHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getAllowedNetworkTypesBitmapResponse(
+            const V1_6::RadioResponseInfo& info,
+            hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+    Return<void> setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getSystemSelectionChannelsResponse(
+            const V1_6::RadioResponseInfo& info,
+            const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) override;
+    Return<void> getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                             const hidl_vec<V1_6::CellInfo>& cellInfo) override;
+    Return<void> getSignalStrengthResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                               const V1_6::SignalStrength& signalStrength) override;
+    Return<void> getVoiceRegistrationStateResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const V1_6::RegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const V1_6::RegStateResult& dataRegResponse) override;
+    Return<void> getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                             const hidl_vec<V1_6::Call>& calls) override;
+    Return<void> getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+                                          const V1_6::SlicingConfig& slicingConfig) override;
+    Return<void> getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getSimPhonebookCapacityResponse(const V1_6::RadioResponseInfo& info,
+                                                 const V1_6::PhonebookCapacity& capacity) override;
+    Return<void> updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+                                                   int32_t updatedRecordIndex) override;
+
+  public:
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+                    radioMessagingResponse);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> modemCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> nwCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
new file mode 100644
index 0000000..a6b77fd
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/sim/BnRadioSim.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio::sim::BnRadioSim {
+    ::ndk::ScopedAStatus areUiccApplicationsEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+                                             const std::string& newPin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus changeIccPinForApp(int32_t serial, const std::string& oldPin,
+                                            const std::string& newPin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus enableUiccApplications(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus getAllowedCarriers(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaSubscription(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaSubscriptionSource(int32_t serial) override;
+    ::ndk::ScopedAStatus getFacilityLockForApp(int32_t serial, const std::string& facility,
+                                               const std::string& password, int32_t serviceClass,
+                                               const std::string& appId) override;
+    ::ndk::ScopedAStatus getIccCardStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus getImsiForApp(int32_t serial, const std::string& aid) override;
+    ::ndk::ScopedAStatus getSimPhonebookCapacity(int32_t serial) override;
+    ::ndk::ScopedAStatus getSimPhonebookRecords(int32_t serial) override;
+    ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
+    ::ndk::ScopedAStatus iccIoForApp(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::IccIo& iccIo) override;
+    ::ndk::ScopedAStatus iccOpenLogicalChannel(int32_t serial, const std::string& aid,
+                                               int32_t p2) override;
+    ::ndk::ScopedAStatus iccTransmitApduBasicChannel(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+    ::ndk::ScopedAStatus iccTransmitApduLogicalChannel(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+    ::ndk::ScopedAStatus reportStkServiceIsRunning(int32_t serial) override;
+    ::ndk::ScopedAStatus requestIccSimAuthentication(int32_t serial, int32_t authContext,
+                                                     const std::string& authData,
+                                                     const std::string& aid) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendEnvelope(int32_t serial, const std::string& command) override;
+    ::ndk::ScopedAStatus sendEnvelopeWithStatus(int32_t serial,
+                                                const std::string& contents) override;
+    ::ndk::ScopedAStatus sendTerminalResponseToSim(int32_t serial,
+                                                   const std::string& commandResponse) override;
+    ::ndk::ScopedAStatus setAllowedCarriers(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::CarrierRestrictions& carriers,
+            ::aidl::android::hardware::radio::sim::SimLockMultiSimPolicy multiSimPolicy) override;
+    ::ndk::ScopedAStatus setCarrierInfoForImsiEncryption(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& imsiEncryptionInfo)
+            override;
+    ::ndk::ScopedAStatus setCdmaSubscriptionSource(
+            int32_t serial,
+            ::aidl::android::hardware::radio::sim::CdmaSubscriptionSource cdmaSub) override;
+    ::ndk::ScopedAStatus setFacilityLockForApp(  //
+            int32_t serial, const std::string& facility, bool lockState, const std::string& passwd,
+            int32_t serviceClass, const std::string& appId) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse>&
+                    radioSimResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication>&
+                    radioSimIndication) override;
+    ::ndk::ScopedAStatus setSimCardPower(
+            int32_t serial, ::aidl::android::hardware::radio::sim::CardPowerState powerUp) override;
+    ::ndk::ScopedAStatus setUiccSubscription(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::SelectUiccSub& uiccSub) override;
+    ::ndk::ScopedAStatus supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPinForApp(int32_t serial, const std::string& pin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+                                             const std::string& pin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPukForApp(int32_t serial, const std::string& puk,
+                                            const std::string& pin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus supplySimDepersonalization(
+            int32_t serial, ::aidl::android::hardware::radio::sim::PersoSubstate persoType,
+            const std::string& controlKey) override;
+    ::ndk::ScopedAStatus updateSimPhonebookRecords(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& recordInfo) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
new file mode 100644
index 0000000..5bf93e0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/voice/BnRadioVoice.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioVoice : public RadioCompatBase,
+                   public aidl::android::hardware::radio::voice::BnRadioVoice {
+    ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
+    ::ndk::ScopedAStatus conference(int32_t serial) override;
+    ::ndk::ScopedAStatus dial(
+            int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
+    ::ndk::ScopedAStatus emergencyDial(
+            int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo,
+            ::aidl::android::hardware::radio::voice::EmergencyServiceCategory categories,
+            const std::vector<std::string>& urns,
+            ::aidl::android::hardware::radio::voice::EmergencyCallRouting routing,
+            bool hasKnownUserIntentEmergency, bool isTesting) override;
+    ::ndk::ScopedAStatus exitEmergencyCallbackMode(int32_t serial) override;
+    ::ndk::ScopedAStatus explicitCallTransfer(int32_t serial) override;
+    ::ndk::ScopedAStatus getCallForwardStatus(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+    ::ndk::ScopedAStatus getCallWaiting(int32_t serial, int32_t serviceClass) override;
+    ::ndk::ScopedAStatus getClip(int32_t serial) override;
+    ::ndk::ScopedAStatus getClir(int32_t serial) override;
+    ::ndk::ScopedAStatus getCurrentCalls(int32_t serial) override;
+    ::ndk::ScopedAStatus getLastCallFailCause(int32_t serial) override;
+    ::ndk::ScopedAStatus getMute(int32_t serial) override;
+    ::ndk::ScopedAStatus getPreferredVoicePrivacy(int32_t serial) override;
+    ::ndk::ScopedAStatus getTtyMode(int32_t serial) override;
+    ::ndk::ScopedAStatus handleStkCallSetupRequestFromSim(int32_t serial, bool accept) override;
+    ::ndk::ScopedAStatus hangup(int32_t serial, int32_t gsmIndex) override;
+    ::ndk::ScopedAStatus hangupForegroundResumeBackground(int32_t serial) override;
+    ::ndk::ScopedAStatus hangupWaitingOrBackground(int32_t serial) override;
+    ::ndk::ScopedAStatus isVoNrEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus rejectCall(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+                                       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 separateConnection(int32_t serial, int32_t gsmIndex) override;
+    ::ndk::ScopedAStatus setCallForward(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+    ::ndk::ScopedAStatus setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) override;
+    ::ndk::ScopedAStatus setClir(int32_t serial, int32_t status) override;
+    ::ndk::ScopedAStatus setMute(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setPreferredVoicePrivacy(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse>&
+                    radioVoiceResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication>&
+                    radioVoiceIndication) override;
+    ::ndk::ScopedAStatus setTtyMode(int32_t serial,
+                                    ::aidl::android::hardware::radio::voice::TtyMode mode) override;
+    ::ndk::ScopedAStatus setVoNrEnabled(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus startDtmf(int32_t serial, const std::string& s) override;
+    ::ndk::ScopedAStatus stopDtmf(int32_t serial) override;
+    ::ndk::ScopedAStatus switchWaitingOrHoldingAndActive(int32_t serial) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
new file mode 100644
index 0000000..c7342b1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "MessagingIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingIndication> rmiCb) {
+    CHECK(rmiCb);
+    mMessagingCb = rmiCb;
+}
+
+Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
+                                         const V1_0::CdmaSmsMessage& msg) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cdmaNewSms(toAidl(type), toAidl(msg));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cdmaRuimSmsStorageFull(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
+                                              const hidl_vec<uint8_t>& data) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newBroadcastSms(toAidl(type), data);
+    return {};
+}
+
+Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSms(toAidl(type), pdu);
+    return {};
+}
+
+Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSmsOnSim(toAidl(type), recordNumber);
+    return {};
+}
+
+Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
+                                                 const hidl_vec<uint8_t>& pdu) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSmsStatusReport(toAidl(type), pdu);
+    return {};
+}
+
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                                     const hidl_string& msg) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+    return {};
+}
+
+Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->simSmsStorageFull(toAidl(type));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
new file mode 100644
index 0000000..c1a82b5
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioMessaging.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Messaging"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioMessaging::acknowledgeIncomingGsmSmsWithPdu(  //
+        int32_t serial, bool success, const std::string& ackPdu) {
+    LOG_CALL << serial << ' ' << success << ' ' << ackPdu;
+    mHal1_5->acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingCdmaSms(  //
+        int32_t serial, const aidl::CdmaSmsAck& smsAck) {
+    LOG_CALL << serial;
+    mHal1_5->acknowledgeLastIncomingCdmaSms(serial, toHidl(smsAck));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingGsmSms(  //
+        int32_t serial, bool success, aidl::SmsAcknowledgeFailCause cause) {
+    LOG_CALL << serial << ' ' << success;
+    mHal1_5->acknowledgeLastIncomingGsmSms(serial, success, V1_0::SmsAcknowledgeFailCause(cause));
+    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);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::deleteSmsOnSim(int32_t serial, int32_t index) {
+    LOG_CALL << serial << ' ' << index;
+    mHal1_5->deleteSmsOnSim(serial, index);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getCdmaBroadcastConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaBroadcastConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getGsmBroadcastConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getGsmBroadcastConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getSmscAddress(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getSmscAddress(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::reportSmsMemoryStatus(int32_t serial, bool available) {
+    LOG_CALL << serial << ' ' << available;
+    mHal1_5->reportSmsMemoryStatus(serial, available);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSms(int32_t serial, const aidl::CdmaSmsMessage& sms) {
+    LOG_CALL << serial;
+    mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSmsExpectMore(int32_t serial, const aidl::CdmaSmsMessage& m) {
+    LOG_CALL << serial;
+    mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendImsSms(int32_t serial, const aidl::ImsSmsMessage& message) {
+    LOG_CALL << serial;
+    mHal1_5->sendImsSms(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSms(int32_t serial, const aidl::GsmSmsMessage& message) {
+    LOG_CALL << serial;
+    mHal1_5->sendSms(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSmsExpectMore(int32_t serial, const aidl::GsmSmsMessage& msg) {
+    LOG_CALL << serial;
+    mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    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);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setCdmaBroadcastConfig(
+        int32_t serial, const std::vector<aidl::CdmaBroadcastSmsConfigInfo>& cfgInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaBroadcastConfig(serial, toHidl(cfgInfo));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastActivation(int32_t serial, bool activate) {
+    LOG_CALL << serial << ' ' << activate;
+    mHal1_5->setGsmBroadcastActivation(serial, activate);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastConfig(
+        int32_t serial, const std::vector<aidl::GsmBroadcastSmsConfigInfo>& configInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setGsmBroadcastConfig(serial, toHidl(configInfo));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioMessagingResponse>& messagingResponse,
+        const std::shared_ptr<aidl::IRadioMessagingIndication>& messagingIndication) {
+    LOG_CALL << messagingResponse << ' ' << messagingIndication;
+
+    CHECK(messagingResponse);
+    CHECK(messagingIndication);
+
+    mRadioResponse->setResponseFunction(messagingResponse);
+    mRadioIndication->setResponseFunction(messagingIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setSmscAddress(int32_t serial, const std::string& smsc) {
+    LOG_CALL << serial << ' ' << smsc;
+    mHal1_5->setSmscAddress(serial, smsc);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToRuim(int32_t serial, const aidl::CdmaSmsWriteArgs& sms) {
+    LOG_CALL << serial;
+    mHal1_5->writeSmsToRuim(serial, toHidl(sms));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToSim(int32_t serial, const aidl::SmsWriteArgs& smsWrArgs) {
+    LOG_CALL << serial;
+    mHal1_5->writeSmsToSim(serial, toHidl(smsWrArgs));
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
new file mode 100644
index 0000000..379e463
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "MessagingResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingResponse> rmrCb) {
+    CHECK(rmrCb);
+    mMessagingCb = rmrCb;
+}
+
+Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cancelPendingUssdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->deleteSmsOnRuimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->deleteSmsOnSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioResponse::getGsmBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& cfg) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
+    return {};
+}
+
+Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+                                                   const hidl_string& smsc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getSmscAddressResponse(toAidl(info), smsc);
+    return {};
+}
+
+Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->reportSmsMemoryStatusResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                                          const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                              const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                    const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendImsSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                          const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendUssdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setCdmaBroadcastActivationResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setCdmaBroadcastConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setGsmBroadcastActivationResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setGsmBroadcastConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setSmscAddressResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+                                                   uint32_t index) {
+    LOG_CALL << info.serial << ' ' << index;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->writeSmsToRuimResponse(toAidl(info), index);
+    return {};
+}
+
+Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
+                                                  int32_t index) {
+    LOG_CALL << info.serial << ' ' << index;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->writeSmsToSimResponse(toAidl(info), index);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.cpp b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
new file mode 100644
index 0000000..9019680
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "collections.h"
+
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAddress.h>
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+V1_0::CdmaSmsAck toHidl(const aidl::CdmaSmsAck& smsAck) {
+    return {
+            .errorClass = (smsAck.errorClass ? V1_0::CdmaSmsErrorClass::ERROR
+                                             : V1_0::CdmaSmsErrorClass::NO_ERROR),
+            .smsCauseCode = smsAck.smsCauseCode,
+    };
+}
+
+static aidl::CdmaSmsAddress toAidl(const V1_0::CdmaSmsAddress& addr) {
+    return {
+            .digitMode = static_cast<int32_t>(addr.digitMode),
+            .isNumberModeDataNetwork = addr.numberMode == V1_0::CdmaSmsNumberMode::DATA_NETWORK,
+            .numberType = static_cast<int32_t>(addr.numberType),
+            .numberPlan = static_cast<int32_t>(addr.numberPlan),
+            .digits = addr.digits,
+    };
+}
+
+static V1_0::CdmaSmsAddress toHidl(const aidl::CdmaSmsAddress& addr) {
+    return {
+            .digitMode = V1_0::CdmaSmsDigitMode{addr.digitMode},
+            .numberMode = addr.isNumberModeDataNetwork ? V1_0::CdmaSmsNumberMode::DATA_NETWORK
+                                                       : V1_0::CdmaSmsNumberMode::NOT_DATA_NETWORK,
+            .numberType = V1_0::CdmaSmsNumberType{addr.numberType},
+            .numberPlan = V1_0::CdmaSmsNumberPlan{addr.numberPlan},
+            .digits = addr.digits,
+    };
+}
+
+static aidl::CdmaSmsSubaddress toAidl(const V1_0::CdmaSmsSubaddress& addr) {
+    return {
+            .subaddressType = static_cast<int32_t>(addr.subaddressType),
+            .odd = addr.odd,
+            .digits = addr.digits,
+    };
+}
+
+static V1_0::CdmaSmsSubaddress toHidl(const aidl::CdmaSmsSubaddress& addr) {
+    return {
+            .subaddressType = V1_0::CdmaSmsSubaddressType{addr.subaddressType},
+            .odd = addr.odd,
+            .digits = addr.digits,
+    };
+}
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& m) {
+    return {
+            .teleserviceId = m.teleserviceId,
+            .isServicePresent = m.isServicePresent,
+            .serviceCategory = m.serviceCategory,
+            .address = toAidl(m.address),
+            .subAddress = toAidl(m.subAddress),
+            .bearerData = m.bearerData,
+    };
+}
+
+V1_0::CdmaSmsMessage toHidl(const aidl::CdmaSmsMessage& msg) {
+    return {
+            .teleserviceId = msg.teleserviceId,
+            .isServicePresent = msg.isServicePresent,
+            .serviceCategory = msg.serviceCategory,
+            .address = toHidl(msg.address),
+            .subAddress = toHidl(msg.subAddress),
+            .bearerData = msg.bearerData,
+    };
+}
+
+V1_0::ImsSmsMessage toHidl(const aidl::ImsSmsMessage& msg) {
+    return {
+            .tech = V1_0::RadioTechnologyFamily{msg.tech},
+            .retry = msg.retry,
+            .messageRef = msg.messageRef,
+            .cdmaMessage = toHidl(msg.cdmaMessage),
+            .gsmMessage = toHidl(msg.gsmMessage),
+    };
+}
+
+V1_0::GsmSmsMessage toHidl(const aidl::GsmSmsMessage& msg) {
+    return {
+            .smscPdu = msg.smscPdu,
+            .pdu = msg.pdu,
+    };
+}
+
+aidl::CdmaBroadcastSmsConfigInfo toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info) {
+    return {
+            .serviceCategory = info.serviceCategory,
+            .language = info.language,
+            .selected = info.selected,
+    };
+}
+
+V1_0::CdmaBroadcastSmsConfigInfo toHidl(const aidl::CdmaBroadcastSmsConfigInfo& info) {
+    return {
+            .serviceCategory = info.serviceCategory,
+            .language = info.language,
+            .selected = info.selected,
+    };
+}
+
+aidl::GsmBroadcastSmsConfigInfo toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info) {
+    return {
+            .fromServiceId = info.fromServiceId,
+            .toServiceId = info.toServiceId,
+            .fromCodeScheme = info.fromCodeScheme,
+            .toCodeScheme = info.toCodeScheme,
+            .selected = info.selected,
+    };
+}
+
+V1_0::GsmBroadcastSmsConfigInfo toHidl(const aidl::GsmBroadcastSmsConfigInfo& info) {
+    return {
+            .fromServiceId = info.fromServiceId,
+            .toServiceId = info.toServiceId,
+            .fromCodeScheme = info.fromCodeScheme,
+            .toCodeScheme = info.toCodeScheme,
+            .selected = info.selected,
+    };
+}
+
+V1_0::CdmaSmsWriteArgs toHidl(const aidl::CdmaSmsWriteArgs& args) {
+    return {
+            .status = V1_0::CdmaSmsWriteArgsStatus{args.status},
+            .message = toHidl(args.message),
+    };
+}
+
+V1_0::SmsWriteArgs toHidl(const aidl::SmsWriteArgs& args) {
+    return {
+            .status = V1_0::SmsWriteArgsStatus{args.status},
+            .pdu = args.pdu,
+            .smsc = args.smsc,
+    };
+}
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(
+        const V1_0::SendSmsResult& result) {
+    return {
+            .messageRef = result.messageRef,
+            .ackPDU = result.ackPDU,
+            .errorCode = result.errorCode,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.h b/radio/aidl/compat/libradiocompat/messaging/structs.h
new file mode 100644
index 0000000..afb4941
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAck.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.h>
+#include <aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/GsmSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/ImsSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/SendSmsResult.h>
+#include <aidl/android/hardware/radio/messaging/SmsWriteArgs.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::CdmaSmsAck toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& ack);
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& msg);
+V1_0::CdmaSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& msg);
+
+V1_0::ImsSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& msg);
+
+V1_0::GsmSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& msg);
+
+::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo  //
+toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info);
+V1_0::CdmaBroadcastSmsConfigInfo  //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo& info);
+
+::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo  //
+toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info);
+V1_0::GsmBroadcastSmsConfigInfo  //
+toHidl(const ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo& info);
+
+V1_0::CdmaSmsWriteArgs  //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& args);
+
+V1_0::SmsWriteArgs toHidl(const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& args);
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(const V1_0::SendSmsResult& res);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
new file mode 100644
index 0000000..8fc4da6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioModemIndication> modemCb) {
+    CHECK(modemCb);
+    mModemCb = modemCb;
+}
+
+Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
+                                                    const hidl_vec<V1_0::HardwareConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->hardwareConfigChanged(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type, const hidl_string& reasn) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->modemReset(toAidl(type), reasn);
+    return {};
+}
+
+Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
+                                                        const V1_0::RadioCapability& rc) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->radioCapabilityIndication(toAidl(type), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType t, V1_0::RadioState st) {
+    LOG_CALL << t;
+    CHECK_CB(mModemCb);
+    mModemCb->radioStateChanged(toAidl(t), aidl::RadioState(st));
+    return {};
+}
+
+Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->rilConnected(toAidl(type));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
new file mode 100644
index 0000000..660ae9f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioModem.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Modem"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
+    LOG_CALL << serial;
+    mHal1_5->enableModem(serial, on);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getBasebandVersion(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getBasebandVersion(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getDeviceIdentity(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDeviceIdentity(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getHardwareConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getModemActivityInfo(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getModemActivityInfo(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getModemStackStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getModemStackStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getRadioCapability(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getRadioCapability(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvReadItem(int32_t serial, aidl::NvItem itemId) {
+    LOG_CALL << serial;
+    mHal1_5->nvReadItem(serial, V1_0::NvItem(itemId));
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvResetConfig(int32_t serial, aidl::ResetNvType resetType) {
+    LOG_CALL << serial;
+    mHal1_5->nvResetConfig(serial, V1_0::ResetNvType(resetType));
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) {
+    LOG_CALL << serial;
+    mHal1_5->nvWriteCdmaPrl(serial, prl);
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteItem(int32_t serial, const aidl::NvWriteItem& item) {
+    LOG_CALL << serial;
+    mHal1_5->nvWriteItem(serial, toHidl(item));
+    return ok();
+}
+
+ScopedAStatus RadioModem::requestShutdown(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->requestShutdown(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioModem::sendDeviceState(int32_t serial, aidl::DeviceStateType type, bool state) {
+    LOG_CALL << serial;
+    mHal1_5->sendDeviceState(serial, V1_0::DeviceStateType(type), state);
+    return ok();
+}
+
+ScopedAStatus RadioModem::setRadioCapability(int32_t serial, const aidl::RadioCapability& rc) {
+    LOG_CALL << serial;
+    mHal1_5->setRadioCapability(serial, toHidl(rc));
+    return ok();
+}
+
+ScopedAStatus RadioModem::setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+                                        bool preferredForEmergencyCall) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setRadioPower_1_6(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+    } else {
+        mHal1_5->setRadioPower_1_5(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioModem::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioModemResponse>& modemResponse,
+        const std::shared_ptr<aidl::IRadioModemIndication>& modemIndication) {
+    LOG_CALL << modemResponse << ' ' << modemIndication;
+
+    CHECK(modemResponse);
+    CHECK(modemIndication);
+
+    mRadioResponse->setResponseFunction(modemResponse);
+    mRadioIndication->setResponseFunction(modemIndication);
+
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
new file mode 100644
index 0000000..300627c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioModemResponse> modemCb) {
+    CHECK(modemCb);
+    mModemCb = modemCb;
+}
+
+Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->enableModemResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+                                                       const hidl_string& version) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getBasebandVersionResponse(toAidl(info), version);
+    return {};
+}
+
+Return<void> RadioResponse::getDeviceIdentityResponse(  //
+        const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+        const hidl_string& esn, const hidl_string& meid) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
+    return {};
+}
+
+Return<void> RadioResponse::getHardwareConfigResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getHardwareConfigResponse(toAidl(info), toAidl(config));
+    return {};
+}
+
+Return<void> RadioResponse::getModemActivityInfoResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                        bool isEnabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getModemStackStatusResponse(toAidl(info), isEnabled);
+    return {};
+}
+
+Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+                                               const hidl_string& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvReadItemResponse(toAidl(info), result);
+    return {};
+}
+
+Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvResetConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvWriteCdmaPrlResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvWriteItemResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->requestShutdownResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->sendDeviceStateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
new file mode 100644
index 0000000..c1cd64c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+V1_0::NvWriteItem toHidl(const aidl::NvWriteItem& item) {
+    return {
+            .itemId = V1_0::NvItem{item.itemId},
+            .value = item.value,
+    };
+}
+
+aidl::RadioCapability toAidl(const V1_0::RadioCapability& capa) {
+    return {
+            .session = capa.session,
+            .phase = static_cast<int32_t>(capa.phase),
+            .raf = RadioAccessFamily(capa.raf),
+            .logicalModemUuid = capa.logicalModemUuid,
+            .status = static_cast<int32_t>(capa.status),
+    };
+}
+
+V1_0::RadioCapability toHidl(const aidl::RadioCapability& capa) {
+    return {
+            .session = capa.session,
+            .phase = V1_0::RadioCapabilityPhase{capa.phase},
+            .raf = toHidlBitfield<V1_0::RadioAccessFamily>(capa.raf),
+            .logicalModemUuid = capa.logicalModemUuid,
+            .status = V1_0::RadioCapabilityStatus{capa.status},
+    };
+}
+
+aidl::HardwareConfig toAidl(const V1_0::HardwareConfig& config) {
+    return {
+            .type = static_cast<int32_t>(config.type),
+            .uuid = config.uuid,
+            .state = static_cast<int32_t>(config.state),
+            .modem = toAidl(config.modem),
+            .sim = toAidl(config.sim),
+    };
+}
+
+aidl::HardwareConfigModem toAidl(const V1_0::HardwareConfigModem& modem) {
+    return {
+            .rilModel = modem.rilModel,
+            .rat = RadioTechnology(modem.rat),
+            .maxVoiceCalls = modem.maxVoice,
+            .maxDataCalls = modem.maxData,
+            .maxStandby = modem.maxStandby,
+    };
+}
+
+aidl::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& sim) {
+    return {
+            .modemUuid = sim.modemUuid,
+    };
+}
+
+aidl::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& info) {
+    return {
+            .sleepModeTimeMs = static_cast<int32_t>(info.sleepModeTimeMs),
+            .idleModeTimeMs = static_cast<int32_t>(info.idleModeTimeMs),
+            .txmModetimeMs = toAidl(info.txmModetimeMs),
+            .rxModeTimeMs = static_cast<int32_t>(info.rxModeTimeMs),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.h b/radio/aidl/compat/libradiocompat/modem/structs.h
new file mode 100644
index 0000000..3ac1edb
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/modem/ActivityStatsInfo.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfig.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigModem.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigSim.h>
+#include <aidl/android/hardware/radio/modem/NvWriteItem.h>
+#include <aidl/android/hardware/radio/modem/RadioCapability.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::NvWriteItem toHidl(const ::aidl::android::hardware::radio::modem::NvWriteItem& item);
+
+::aidl::android::hardware::radio::modem::RadioCapability toAidl(const V1_0::RadioCapability& capa);
+V1_0::RadioCapability toHidl(const ::aidl::android::hardware::radio::modem::RadioCapability& capa);
+
+::aidl::android::hardware::radio::modem::HardwareConfig toAidl(const V1_0::HardwareConfig& config);
+
+::aidl::android::hardware::radio::modem::HardwareConfigModem  //
+toAidl(const V1_0::HardwareConfigModem& modem);
+
+::aidl::android::hardware::radio::modem::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& s);
+
+::aidl::android::hardware::radio::modem::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& i);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
new file mode 100644
index 0000000..899b133
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkIndication"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkIndication> netCb) {
+    CHECK(netCb);
+    mNetworkCb = netCb;
+}
+
+Return<void> RadioIndication::barringInfoChanged(V1_0::RadioIndicationType type,
+                                                 const V1_5::CellIdentity& cellIdentity,
+                                                 const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cdmaPrlChanged(toAidl(type), version);
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList(V1_0::RadioIndicationType type,
+                                           const hidl_vec<V1_0::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_2(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_2::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_4(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_4::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_5(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_5::CellInfo>& records) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_6(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_6::CellInfo>& records) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+                                                          const V1_2::LinkCapacityEstimate& lce) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate_1_6(
+        V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_2::PhysicalChannelConfig>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_6(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_6::PhysicalChannelConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength(V1_0::RadioIndicationType type,
+                                                    const V1_0::SignalStrength&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+                                                        const V1_2::SignalStrength&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_4(
+        V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_6(
+        V1_0::RadioIndicationType type, const V1_6::SignalStrength& signalStrength) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->imsNetworkStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult(V1_0::RadioIndicationType type,
+                                                const V1_1::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_2(V1_0::RadioIndicationType type,
+                                                    const V1_2::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_4(V1_0::RadioIndicationType type,
+                                                    const V1_4::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_5(V1_0::RadioIndicationType type,
+                                                    const V1_5::NetworkScanResult& result) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_6(V1_0::RadioIndicationType type,
+                                                    const V1_6::NetworkScanResult& result) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    return {};
+}
+
+Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
+                                               const hidl_string& nitzTime, uint64_t receivedTime) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
+    return {};
+}
+
+Return<void> RadioIndication::registrationFailed(  //
+        V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+        const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+        int32_t additionalCauseCode) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn,
+                                   aidl::Domain(domain), causeCode, additionalCauseCode);
+    return {};
+}
+
+Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
+                                                     V1_0::PhoneRestrictedState state) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
+    return {};
+}
+
+Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
+                                            const V1_0::SuppSvcNotification& suppSvc) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->suppSvcNotify(toAidl(type), toAidl(suppSvc));
+    return {};
+}
+
+Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
+                                                    V1_0::RadioTechnology rat) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
+    return {};
+}
+
+Return<void> RadioIndication::lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo&) {
+    LOG_CALL << type;
+    LOG(WARNING) << "lceData indication is deprecated";
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
new file mode 100644
index 0000000..af0bc46
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioNetwork.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Network"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::network;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getAllowedNetworkTypesBitmap(serial);
+    } else {
+        mHal1_5->getPreferredNetworkType(serial);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableBandModes(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAvailableBandModes(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableNetworks(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAvailableNetworks(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getBarringInfo(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getBarringInfo(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getCdmaRoamingPreference(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaRoamingPreference(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCellInfoList(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getDataRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDataRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getImsRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getImsRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getNetworkSelectionMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getNetworkSelectionMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getOperator(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getOperator(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getSignalStrength(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getSignalStrength(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getSystemSelectionChannels(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSystemSelectionChannels(serial);
+    } else {
+        respond().getSystemSelectionChannelsResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRadioTechnology(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getVoiceRadioTechnology(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getVoiceRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::isNrDualConnectivityEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->isNrDualConnectivityEnabled(serial);
+    } else {
+        respond().isNrDualConnectivityEnabledResponse(notSupported(serial), false);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, RadioAccessFamily ntype) {
+    LOG_CALL << serial;
+    const auto raf = toHidlBitfield<V1_4::RadioAccessFamily>(ntype);
+    if (mHal1_6) {
+        mHal1_6->setAllowedNetworkTypesBitmap(serial, raf);
+    } else {
+        mHal1_5->setPreferredNetworkType(serial, getNetworkTypeFromRaf(raf));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setBandMode(int32_t serial, aidl::RadioBandMode mode) {
+    LOG_CALL << serial;
+    mHal1_5->setBandMode(serial, V1_0::RadioBandMode(mode));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setBarringPassword(int32_t serial, const std::string& facility,
+                                               const std::string& oldPw, const std::string& newPw) {
+    LOG_CALL << serial;
+    mHal1_5->setBarringPassword(serial, facility, oldPw, newPw);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setCdmaRoamingPreference(int32_t serial, aidl::CdmaRoamingType type) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaRoamingPreference(serial, V1_0::CdmaRoamingType(type));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setCellInfoListRate(int32_t serial, int32_t rate) {
+    LOG_CALL << serial;
+    mHal1_5->setCellInfoListRate(serial, rate);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, aidl::IndicationFilter indFilter) {
+    LOG_CALL << serial;
+    mHal1_5->setIndicationFilter(serial, toHidlBitfield<V1_0::IndicationFilter>(indFilter));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setLinkCapacityReportingCriteria(  //
+        int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
+        const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
+        AccessNetwork accessNetwork) {
+    LOG_CALL << serial;
+    mHal1_5->setLinkCapacityReportingCriteria(  //
+            serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps, thrDownlinkKbps,
+            thrUplinkKbps, V1_2::AccessNetwork(accessNetwork));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setLocationUpdates(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setLocationUpdates(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeAutomatic(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->setNetworkSelectionModeAutomatic(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeManual(  //
+        int32_t serial, const std::string& opNumeric, AccessNetwork ran) {
+    LOG_CALL << serial;
+    mHal1_5->setNetworkSelectionModeManual_1_5(serial, opNumeric, V1_5::RadioAccessNetworks(ran));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNrDualConnectivityState(int32_t serial,
+                                                       aidl::NrDualConnectivityState st) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setNrDualConnectivityState(serial, V1_6::NrDualConnectivityState(st));
+    } else {
+        respond().setNrDualConnectivityStateResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioNetworkResponse>& networkResponse,
+        const std::shared_ptr<aidl::IRadioNetworkIndication>& networkIndication) {
+    LOG_CALL << networkResponse << ' ' << networkIndication;
+
+    CHECK(networkResponse);
+    CHECK(networkIndication);
+
+    mRadioResponse->setResponseFunction(networkResponse);
+    mRadioIndication->setResponseFunction(networkIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
+        int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): how about other infos?
+    mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
+                                                    V1_5::AccessNetwork(infos[0].ran));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSuppServiceNotifications(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setSuppServiceNotifications(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSystemSelectionChannels(  //
+        int32_t serial, bool specifyCh, const std::vector<aidl::RadioAccessSpecifier>& specifiers) {
+    LOG_CALL << serial;
+    mHal1_5->setSystemSelectionChannels_1_5(serial, specifyCh, toHidl(specifiers));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::startNetworkScan(int32_t serial, const aidl::NetworkScanRequest& req) {
+    LOG_CALL << serial;
+    mHal1_5->startNetworkScan_1_5(serial, toHidl(req));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::stopNetworkScan(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->stopNetworkScan(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::supplyNetworkDepersonalization(int32_t ser, const std::string& nPin) {
+    LOG_CALL << ser;
+    mHal1_5->supplyNetworkDepersonalization(ser, nPin);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
new file mode 100644
index 0000000..81f7775
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkResponse"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+using ::aidl::android::hardware::radio::RadioTechnologyFamily;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkResponse> netCb) {
+    CHECK(netCb);
+    mNetworkCb = netCb;
+}
+
+Return<void> RadioResponse::getAllowedNetworkTypesBitmapResponse(
+        const V1_6::RadioResponseInfo& info,
+        hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAllowedNetworkTypesBitmapResponse(toAidl(info),
+                                                     RadioAccessFamily(networkTypeBitmap));
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::PreferredNetworkType nwType) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAllowedNetworkTypesBitmapResponse(  //
+            toAidl(info), RadioAccessFamily(getRafFromNetworkType(nwType)));
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info, hidl_bitfield<V1_4::RadioAccessFamily>) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getAvailableBandModesResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
+    return {};
+}
+
+Return<void> RadioResponse::getAvailableNetworksResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getBarringInfoResponse(
+        const V1_0::RadioResponseInfo& info, const V1_5::CellIdentity& cellIdentity,
+        const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+                                                             V1_0::CdmaRoamingType type) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_4::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_5::CellInfo>& cellInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_6::CellInfo>& cellInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                             const V1_0::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_5(
+        const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& dataRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& dataRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getImsRegistrationStateResponse(  //
+        const V1_0::RadioResponseInfo& info, bool isRegd, V1_0::RadioTechnologyFamily ratFamily) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getImsRegistrationStateResponse(toAidl(info), isRegd,
+                                                RadioTechnologyFamily(ratFamily));
+    return {};
+}
+
+Return<void> RadioResponse::getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+                                                       const hidl_vec<V1_0::NeighboringCell>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "getNeighboringCidsResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+                                                            bool manual) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getNetworkSelectionModeResponse(toAidl(info), manual);
+    return {};
+}
+
+Return<void> RadioResponse::getOperatorResponse(  //
+        const V1_0::RadioResponseInfo& info, const hidl_string& longName,
+        const hidl_string& shortName, const hidl_string& numeric) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getOperatorResponse(toAidl(info), longName, shortName, numeric);
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SignalStrength&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                          const V1_2::SignalStrength&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::SignalStrength& signalStrength) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioResponse::getSystemSelectionChannelsResponse(
+        const V1_6::RadioResponseInfo& info,
+        const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::RadioTechnology rat) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                              const V1_0::VoiceRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::VoiceRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_5(
+        const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& voiceRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& voiceRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+                                                                bool isEnabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
+    return {};
+}
+
+Return<void> RadioResponse::pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::LceDataInfo&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "pullLceDataResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& i) {
+    LOG_CALL << i.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(i));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setBandModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setBarringPasswordResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setCdmaRoamingPreferenceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setCellInfoListRateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLocationUpdatesResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeAutomaticResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNrDualConnectivityStateResponse(
+        const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNrDualConnectivityStateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSuppServiceNotificationsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSuppServiceNotificationsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->stopNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
+        const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                    const V1_0::LceStatusInfo&) {
+    LOG_CALL << info.serial;
+    LOG(WARNING) << "startLceServiceResponse is deprecated";
+    return {};
+}
+
+Return<void> RadioResponse::stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_0::LceStatusInfo&) {
+    LOG_CALL << info.serial;
+    LOG(WARNING) << "stopLceServiceResponse is deprecated";
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
new file mode 100644
index 0000000..87a021f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::network;
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioTechnology;
+
+aidl::RadioBandMode toAidl(V1_0::RadioBandMode mode) {
+    return aidl::RadioBandMode(mode);
+}
+
+aidl::GeranBands toAidl(V1_1::GeranBands band) {
+    return aidl::GeranBands(band);
+}
+
+V1_1::GeranBands toHidl(aidl::GeranBands band) {
+    return V1_1::GeranBands(band);
+}
+
+aidl::UtranBands toAidl(V1_5::UtranBands band) {
+    return aidl::UtranBands(band);
+}
+
+V1_5::UtranBands toHidl(aidl::UtranBands band) {
+    return V1_5::UtranBands(band);
+}
+
+aidl::EutranBands toAidl(V1_5::EutranBands band) {
+    return aidl::EutranBands(band);
+}
+
+V1_5::EutranBands toHidl(aidl::EutranBands band) {
+    return V1_5::EutranBands(band);
+}
+
+aidl::NgranBands toAidl(V1_5::NgranBands band) {
+    return aidl::NgranBands(band);
+}
+
+V1_5::NgranBands toHidl(aidl::NgranBands band) {
+    return V1_5::NgranBands(band);
+}
+
+V1_5::SignalThresholdInfo toHidl(const aidl::SignalThresholdInfo& info) {
+    return {
+            .signalMeasurement = V1_5::SignalMeasurementType{info.signalMeasurement},
+            .hysteresisMs = info.hysteresisMs,
+            .hysteresisDb = info.hysteresisDb,
+            .thresholds = info.thresholds,
+            .isEnabled = info.isEnabled,
+    };
+}
+
+static aidl::RadioAccessSpecifierBands toAidl(const V1_5::RadioAccessSpecifier::Bands& bands) {
+    using Discr = V1_5::RadioAccessSpecifier::Bands::hidl_discriminator;
+    const auto discr = bands.getDiscriminator();
+
+    if (discr == Discr::geranBands) return toAidl(bands.geranBands());
+    if (discr == Discr::utranBands) return toAidl(bands.utranBands());
+    if (discr == Discr::eutranBands) return toAidl(bands.eutranBands());
+    if (discr == Discr::ngranBands) return toAidl(bands.ngranBands());
+
+    return {};
+}
+
+static V1_5::RadioAccessSpecifier::Bands toHidl(const aidl::RadioAccessSpecifierBands& bands) {
+    V1_5::RadioAccessSpecifier::Bands hidl;
+    using Tag = aidl::RadioAccessSpecifierBands::Tag;
+
+    if (bands.getTag() == Tag::geranBands) hidl.geranBands(toHidl(bands.get<Tag::geranBands>()));
+    if (bands.getTag() == Tag::utranBands) hidl.utranBands(toHidl(bands.get<Tag::utranBands>()));
+    if (bands.getTag() == Tag::eutranBands) hidl.eutranBands(toHidl(bands.get<Tag::eutranBands>()));
+    if (bands.getTag() == Tag::ngranBands) hidl.ngranBands(toHidl(bands.get<Tag::ngranBands>()));
+
+    return hidl;
+}
+
+aidl::RadioAccessSpecifier toAidl(const V1_5::RadioAccessSpecifier& spec) {
+    return {
+            .accessNetwork = AccessNetwork(spec.radioAccessNetwork),
+            .bands = toAidl(spec.bands),
+            .channels = spec.channels,
+    };
+}
+
+V1_5::RadioAccessSpecifier toHidl(const aidl::RadioAccessSpecifier& spec) {
+    return {
+            .radioAccessNetwork = V1_5::RadioAccessNetworks{spec.accessNetwork},
+            .bands = toHidl(spec.bands),
+            .channels = spec.channels,
+    };
+}
+
+V1_5::NetworkScanRequest toHidl(const aidl::NetworkScanRequest& req) {
+    return {
+            .type = V1_1::ScanType{req.type},
+            .interval = req.interval,
+            .specifiers = toHidl(req.specifiers),
+            .maxSearchTime = req.maxSearchTime,
+            .incrementalResults = req.incrementalResults,
+            .incrementalResultsPeriodicity = req.incrementalResultsPeriodicity,
+            .mccMncs = toHidl(req.mccMncs),
+    };
+}
+
+static aidl::OperatorInfo toAidl(const V1_2::CellIdentityOperatorNames& names) {
+    return {
+            .alphaLong = names.alphaLong,
+            .alphaShort = names.alphaShort,
+            .operatorNumeric = "",
+            .status = aidl::OperatorInfo::STATUS_UNKNOWN,
+    };
+}
+
+static aidl::CellIdentityGsm toAidl(const V1_5::CellIdentityGsm& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .arfcn = ci.base.base.arfcn,
+            .bsic = static_cast<int8_t>(ci.base.base.bsic),
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+    };
+}
+
+aidl::ClosedSubscriberGroupInfo toAidl(const V1_5::ClosedSubscriberGroupInfo& info) {
+    return {
+            .csgIndication = info.csgIndication,
+            .homeNodebName = info.homeNodebName,
+            .csgIdentity = info.csgIdentity,
+    };
+}
+
+static std::optional<aidl::ClosedSubscriberGroupInfo> toAidl(const V1_5::OptionalCsgInfo& opt) {
+    using descr = V1_5::OptionalCsgInfo::hidl_discriminator;
+    if (opt.getDiscriminator() == descr::noinit) return std::nullopt;
+    return toAidl(opt.csgInfo());
+}
+
+static aidl::CellIdentityWcdma toAidl(const V1_5::CellIdentityWcdma& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .psc = ci.base.base.psc,
+            .uarfcn = ci.base.base.uarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+    };
+}
+
+static aidl::CellIdentityTdscdma toAidl(const V1_5::CellIdentityTdscdma& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .cpid = ci.base.base.cpid,
+            .uarfcn = ci.base.uarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+    };
+}
+
+static aidl::CellIdentityCdma toAidl(const V1_2::CellIdentityCdma& ci) {
+    return {
+            .networkId = ci.base.networkId,
+            .systemId = ci.base.systemId,
+            .baseStationId = ci.base.baseStationId,
+            .longitude = ci.base.longitude,
+            .latitude = ci.base.latitude,
+            .operatorNames = toAidl(ci.operatorNames),
+    };
+}
+
+static aidl::CellIdentityLte toAidl(const V1_5::CellIdentityLte& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .ci = ci.base.base.ci,
+            .pci = ci.base.base.pci,
+            .tac = ci.base.base.tac,
+            .earfcn = ci.base.base.earfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .bandwidth = ci.base.bandwidth,
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+            .bands = toAidl(ci.bands),
+    };
+}
+
+static aidl::CellIdentityNr toAidl(const V1_5::CellIdentityNr& ci) {
+    return {
+            .mcc = ci.base.mcc,
+            .mnc = ci.base.mnc,
+            .nci = static_cast<int64_t>(ci.base.nci),
+            .pci = static_cast<int32_t>(ci.base.pci),
+            .tac = ci.base.tac,
+            .nrarfcn = ci.base.nrarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .bands = toAidl(ci.bands),
+    };
+}
+
+aidl::CellIdentity toAidl(const V1_5::CellIdentity& ci) {
+    using Discr = V1_5::CellIdentity::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+
+    return {};
+}
+
+static std::optional<aidl::BarringTypeSpecificInfo>  //
+toAidl(const V1_5::BarringInfo::BarringTypeSpecificInfo& opt) {
+    using discr = V1_5::BarringInfo::BarringTypeSpecificInfo::hidl_discriminator;
+    if (opt.getDiscriminator() == discr::noinit) return std::nullopt;
+
+    const auto& info = opt.conditional();
+    return aidl::BarringTypeSpecificInfo{
+            .factor = info.factor,
+            .timeSeconds = info.timeSeconds,
+            .isBarred = info.isBarred,
+    };
+}
+
+aidl::BarringInfo toAidl(const V1_5::BarringInfo& info) {
+    return {
+            .serviceType = static_cast<int32_t>(info.serviceType),
+            .barringType = static_cast<int32_t>(info.barringType),
+            .barringTypeSpecificInfo = toAidl(info.barringTypeSpecificInfo),
+    };
+}
+
+static aidl::GsmSignalStrength toAidl(const V1_0::GsmSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.signalStrength),
+            .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+            .timingAdvance = sig.timingAdvance,
+    };
+}
+
+static aidl::CellInfoGsm toAidl(const V1_5::CellInfoGsm& info) {
+    return {
+            .cellIdentityGsm = toAidl(info.cellIdentityGsm),
+            .signalStrengthGsm = toAidl(info.signalStrengthGsm),
+    };
+}
+
+static aidl::WcdmaSignalStrength toAidl(const V1_2::WcdmaSignalStrength& sig) {
+    return {
+            .signalStrength = sig.base.signalStrength,
+            .bitErrorRate = sig.base.bitErrorRate,
+            .rscp = static_cast<int32_t>(sig.rscp),
+            .ecno = static_cast<int32_t>(sig.ecno),
+    };
+}
+
+static aidl::CellInfoWcdma toAidl(const V1_5::CellInfoWcdma& info) {
+    return {
+            .cellIdentityWcdma = toAidl(info.cellIdentityWcdma),
+            .signalStrengthWcdma = toAidl(info.signalStrengthWcdma),
+    };
+}
+
+static aidl::TdscdmaSignalStrength toAidl(const V1_2::TdscdmaSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.signalStrength),
+            .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+            .rscp = static_cast<int32_t>(sig.rscp),
+    };
+}
+
+static aidl::CellInfoTdscdma toAidl(const V1_5::CellInfoTdscdma& info) {
+    return {
+            .cellIdentityTdscdma = toAidl(info.cellIdentityTdscdma),
+            .signalStrengthTdscdma = toAidl(info.signalStrengthTdscdma),
+    };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_6::LteSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.base.signalStrength),
+            .rsrp = static_cast<int32_t>(sig.base.rsrp),
+            .rsrq = static_cast<int32_t>(sig.base.rsrq),
+            .rssnr = sig.base.rssnr,
+            .cqi = static_cast<int32_t>(sig.base.cqi),
+            .timingAdvance = static_cast<int32_t>(sig.base.timingAdvance),
+            .cqiTableIndex = static_cast<int32_t>(sig.cqiTableIndex),
+    };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_0::LteSignalStrength& sig) {
+    return toAidl({sig, 0});
+}
+
+static aidl::CellInfoLte toAidl(const V1_5::CellInfoLte& info) {
+    return {
+            .cellIdentityLte = toAidl(info.cellIdentityLte),
+            .signalStrengthLte = toAidl(info.signalStrengthLte),
+    };
+}
+
+static aidl::CellInfoLte toAidl(const V1_6::CellInfoLte& info) {
+    return {
+            .cellIdentityLte = toAidl(info.cellIdentityLte),
+            .signalStrengthLte = toAidl(info.signalStrengthLte),
+    };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_6::NrSignalStrength& sig) {
+    return {
+            .ssRsrp = sig.base.ssRsrp,
+            .ssRsrq = sig.base.ssRsrq,
+            .ssSinr = sig.base.ssSinr,
+            .csiRsrp = sig.base.csiRsrp,
+            .csiRsrq = sig.base.csiRsrq,
+            .csiSinr = sig.base.csiSinr,
+            .csiCqiTableIndex = static_cast<int32_t>(sig.csiCqiTableIndex),
+            .csiCqiReport = sig.csiCqiReport,
+    };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_4::NrSignalStrength& sig) {
+    return toAidl({sig, 0, 0});
+}
+
+static aidl::CellInfoNr toAidl(const V1_5::CellInfoNr& info) {
+    return {
+            .cellIdentityNr = toAidl(info.cellIdentityNr),
+            .signalStrengthNr = toAidl(info.signalStrengthNr),
+    };
+}
+
+static aidl::CellInfoNr toAidl(const V1_6::CellInfoNr& info) {
+    return {
+            .cellIdentityNr = toAidl(info.cellIdentityNr),
+            .signalStrengthNr = toAidl(info.signalStrengthNr),
+    };
+}
+
+static aidl::CdmaSignalStrength toAidl(const V1_0::CdmaSignalStrength& sig) {
+    return {
+            .dbm = static_cast<int32_t>(sig.dbm),
+            .ecio = static_cast<int32_t>(sig.ecio),
+    };
+}
+
+static aidl::EvdoSignalStrength toAidl(const V1_0::EvdoSignalStrength& sig) {
+    return {
+            .dbm = static_cast<int32_t>(sig.dbm),
+            .ecio = static_cast<int32_t>(sig.ecio),
+            .signalNoiseRatio = static_cast<int32_t>(sig.signalNoiseRatio),
+    };
+}
+
+static aidl::CellInfoCdma toAidl(const V1_2::CellInfoCdma& info) {
+    return {
+            .cellIdentityCdma = toAidl(info.cellIdentityCdma),
+            .signalStrengthCdma = toAidl(info.signalStrengthCdma),
+            .signalStrengthEvdo = toAidl(info.signalStrengthEvdo),
+    };
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_5::CellInfo::CellInfoRatSpecificInfo& ci) {
+    using Discr = V1_5::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+    return {};
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_6::CellInfo::CellInfoRatSpecificInfo& ci) {
+    using Discr = V1_6::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+    return {};
+}
+
+aidl::CellInfo toAidl(const V1_5::CellInfo& info) {
+    return {
+            .registered = info.registered,
+            // ignored: timeStampType and timeStamp
+            .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+            .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+    };
+}
+
+aidl::CellInfo toAidl(const V1_6::CellInfo& info) {
+    return {
+            .registered = info.registered,
+            .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+            .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+    };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_2::LinkCapacityEstimate& e) {
+    return {
+            .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+            .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+    };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_6::LinkCapacityEstimate& e) {
+    return {
+            .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+            .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+            .secondaryDownlinkCapacityKbps = static_cast<int32_t>(e.secondaryDownlinkCapacityKbps),
+            .secondaryUplinkCapacityKbps = static_cast<int32_t>(e.secondaryUplinkCapacityKbps),
+    };
+}
+
+static aidl::PhysicalChannelConfigBand toAidl(const V1_6::PhysicalChannelConfig::Band& band) {
+    using Discr = V1_6::PhysicalChannelConfig::Band::hidl_discriminator;
+    const auto discr = band.getDiscriminator();
+
+    if (discr == Discr::geranBand) return aidl::GeranBands(band.geranBand());
+    if (discr == Discr::utranBand) return aidl::UtranBands(band.utranBand());
+    if (discr == Discr::eutranBand) return aidl::EutranBands(band.eutranBand());
+    if (discr == Discr::ngranBand) return aidl::NgranBands(band.ngranBand());
+
+    return {};
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_4::PhysicalChannelConfig& cfg) {
+    int32_t downlinkChannelNumber = 0;
+    // ignored rfInfo.range
+    using Discr = V1_4::RadioFrequencyInfo::hidl_discriminator;
+    if (cfg.rfInfo.getDiscriminator() == Discr::channelNumber) {
+        downlinkChannelNumber = cfg.rfInfo.channelNumber();
+    }
+
+    return {
+            .status = aidl::CellConnectionStatus(cfg.base.status),
+            .rat = RadioTechnology(cfg.rat),
+            .downlinkChannelNumber = downlinkChannelNumber,
+            .cellBandwidthDownlinkKhz = cfg.base.cellBandwidthDownlink,
+            .contextIds = cfg.contextIds,
+            .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+    };
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_6::PhysicalChannelConfig& cfg) {
+    return {
+            .status = aidl::CellConnectionStatus(cfg.status),
+            .rat = RadioTechnology(cfg.rat),
+            .downlinkChannelNumber = cfg.downlinkChannelNumber,
+            .uplinkChannelNumber = cfg.uplinkChannelNumber,
+            .cellBandwidthDownlinkKhz = cfg.cellBandwidthDownlinkKhz,
+            .cellBandwidthUplinkKhz = cfg.cellBandwidthUplinkKhz,
+            .contextIds = cfg.contextIds,
+            .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+            .band = toAidl(cfg.band),
+    };
+}
+
+aidl::SignalStrength toAidl(const V1_4::SignalStrength& sig) {
+    return {
+            .gsm = toAidl(sig.gsm),
+            .cdma = toAidl(sig.cdma),
+            .evdo = toAidl(sig.evdo),
+            .lte = toAidl(sig.lte),
+            .tdscdma = toAidl(sig.tdscdma),
+            .wcdma = toAidl(sig.wcdma),
+            .nr = toAidl(sig.nr),
+    };
+}
+
+aidl::SignalStrength toAidl(const V1_6::SignalStrength& sig) {
+    return {
+            .gsm = toAidl(sig.gsm),
+            .cdma = toAidl(sig.cdma),
+            .evdo = toAidl(sig.evdo),
+            .lte = toAidl(sig.lte),
+            .tdscdma = toAidl(sig.tdscdma),
+            .wcdma = toAidl(sig.wcdma),
+            .nr = toAidl(sig.nr),
+    };
+}
+
+aidl::NetworkScanResult toAidl(const V1_5::NetworkScanResult& res) {
+    return {
+            .status = static_cast<int32_t>(res.status),
+            .error = toAidl(res.error),
+            .networkInfos = toAidl(res.networkInfos),
+    };
+}
+
+aidl::NetworkScanResult toAidl(const V1_6::NetworkScanResult& res) {
+    return {
+            .status = static_cast<int32_t>(res.status),
+            .error = toAidl(res.error),
+            .networkInfos = toAidl(res.networkInfos),
+    };
+}
+
+aidl::SuppSvcNotification toAidl(const V1_0::SuppSvcNotification& svc) {
+    return {
+            .isMT = svc.isMT,
+            .code = svc.code,
+            .index = svc.index,
+            .type = svc.type,
+            .number = svc.number,
+    };
+}
+
+aidl::OperatorInfo toAidl(const V1_0::OperatorInfo& info) {
+    return {
+            .alphaLong = info.alphaLong,
+            .alphaShort = info.alphaShort,
+            .operatorNumeric = info.operatorNumeric,
+            .status = static_cast<int32_t>(info.status),
+    };
+}
+
+static aidl::Cdma2000RegistrationInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::Cdma2000RegistrationInfo& info) {
+    return {
+            .cssSupported = info.cssSupported,
+            .roamingIndicator = info.roamingIndicator,
+            .systemIsInPrl = static_cast<int32_t>(info.systemIsInPrl),
+            .defaultRoamingIndicator = info.defaultRoamingIndicator,
+    };
+}
+
+static aidl::LteVopsInfo toAidl(const V1_4::LteVopsInfo& info) {
+    return {
+            .isVopsSupported = info.isVopsSupported,
+            .isEmcBearerSupported = info.isEmcBearerSupported,
+    };
+}
+
+static aidl::NrIndicators toAidl(const V1_4::NrIndicators& info) {
+    return {
+            .isEndcAvailable = info.isEndcAvailable,
+            .isDcNrRestricted = info.isDcNrRestricted,
+            .isNrAvailable = info.isNrAvailable,
+    };
+}
+
+static aidl::EutranRegistrationInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::EutranRegistrationInfo& info) {
+    return {
+            .lteVopsInfo = toAidl(info.lteVopsInfo),
+            .nrIndicators = toAidl(info.nrIndicators),
+    };
+}
+
+static aidl::NrVopsInfo toAidl(const V1_6::NrVopsInfo& info) {
+    return {
+            .vopsSupported = static_cast<int8_t>(info.vopsSupported),
+            .emcSupported = static_cast<int8_t>(info.emcSupported),
+            .emfSupported = static_cast<int8_t>(info.emfSupported),
+    };
+}
+
+static aidl::AccessTechnologySpecificInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo& info) {
+    using Discr = V1_5::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+    const auto discr = info.getDiscriminator();
+
+    if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+    if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+
+    return {};
+}
+
+static aidl::AccessTechnologySpecificInfo  //
+toAidl(const V1_6::RegStateResult::AccessTechnologySpecificInfo& info) {
+    using Discr = V1_6::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+    const auto discr = info.getDiscriminator();
+
+    if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+    if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+    if (discr == Discr::ngranNrVopsInfo) return toAidl(info.ngranNrVopsInfo());
+    if (discr == Discr::geranDtmSupported) {
+        using T = aidl::AccessTechnologySpecificInfo;
+        return T::make<T::Tag::geranDtmSupported>(info.geranDtmSupported());
+    }
+
+    return {};
+}
+
+aidl::RegStateResult toAidl(const V1_5::RegStateResult& res) {
+    return {
+            .regState = aidl::RegState(res.regState),
+            .rat = RadioTechnology(res.rat),
+            .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+            .cellIdentity = toAidl(res.cellIdentity),
+            .registeredPlmn = res.registeredPlmn,
+            .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+    };
+}
+
+aidl::RegStateResult toAidl(const V1_6::RegStateResult& res) {
+    return {
+            .regState = aidl::RegState(res.regState),
+            .rat = RadioTechnology(res.rat),
+            .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+            .cellIdentity = toAidl(res.cellIdentity),
+            .registeredPlmn = res.registeredPlmn,
+            .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+    };
+}
+
+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),
+            .confidenceLevel = static_cast<int8_t>(info.confidenceLevel),
+            .lceSuspended = info.lceSuspended,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.h b/radio/aidl/compat/libradiocompat/network/structs.h
new file mode 100644
index 0000000..854cb38
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/network/BarringInfo.h>
+#include <aidl/android/hardware/radio/network/CellIdentity.h>
+#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>
+#include <aidl/android/hardware/radio/network/PhysicalChannelConfig.h>
+#include <aidl/android/hardware/radio/network/RadioAccessSpecifier.h>
+#include <aidl/android/hardware/radio/network/RadioBandMode.h>
+#include <aidl/android/hardware/radio/network/RegStateResult.h>
+#include <aidl/android/hardware/radio/network/SignalStrength.h>
+#include <aidl/android/hardware/radio/network/SignalThresholdInfo.h>
+#include <aidl/android/hardware/radio/network/SuppSvcNotification.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+::aidl::android::hardware::radio::network::RadioBandMode toAidl(V1_0::RadioBandMode mode);
+::aidl::android::hardware::radio::network::GeranBands toAidl(V1_1::GeranBands band);
+V1_1::GeranBands toHidl(::aidl::android::hardware::radio::network::GeranBands band);
+::aidl::android::hardware::radio::network::UtranBands toAidl(V1_5::UtranBands band);
+V1_5::UtranBands toHidl(::aidl::android::hardware::radio::network::UtranBands band);
+::aidl::android::hardware::radio::network::EutranBands toAidl(V1_5::EutranBands band);
+V1_5::EutranBands toHidl(::aidl::android::hardware::radio::network::EutranBands band);
+::aidl::android::hardware::radio::network::NgranBands toAidl(V1_5::NgranBands band);
+V1_5::NgranBands toHidl(::aidl::android::hardware::radio::network::NgranBands band);
+
+V1_5::SignalThresholdInfo  //
+toHidl(const ::aidl::android::hardware::radio::network::SignalThresholdInfo& info);
+
+::aidl::android::hardware::radio::network::RadioAccessSpecifier  //
+toAidl(const V1_5::RadioAccessSpecifier& spec);
+V1_5::RadioAccessSpecifier  //
+toHidl(const ::aidl::android::hardware::radio::network::RadioAccessSpecifier& spec);
+
+V1_5::NetworkScanRequest  //
+toHidl(const ::aidl::android::hardware::radio::network::NetworkScanRequest& req);
+
+::aidl::android::hardware::radio::network::CellIdentity toAidl(const V1_5::CellIdentity& ci);
+
+::aidl::android::hardware::radio::network::BarringInfo toAidl(const V1_5::BarringInfo& info);
+
+::aidl::android::hardware::radio::network::ClosedSubscriberGroupInfo  //
+toAidl(const V1_5::ClosedSubscriberGroupInfo& info);
+
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_5::CellInfo& info);
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_6::CellInfo& info);
+
+::aidl::android::hardware::radio::network::LinkCapacityEstimate  //
+toAidl(const V1_2::LinkCapacityEstimate& lce);
+::aidl::android::hardware::radio::network::LinkCapacityEstimate  //
+toAidl(const V1_6::LinkCapacityEstimate& lce);
+
+::aidl::android::hardware::radio::network::PhysicalChannelConfig  //
+toAidl(const V1_4::PhysicalChannelConfig& cfg);
+::aidl::android::hardware::radio::network::PhysicalChannelConfig  //
+toAidl(const V1_6::PhysicalChannelConfig& cfg);
+
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_4::SignalStrength& sig);
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_6::SignalStrength& sig);
+
+::aidl::android::hardware::radio::network::NetworkScanResult  //
+toAidl(const V1_5::NetworkScanResult& res);
+::aidl::android::hardware::radio::network::NetworkScanResult  //
+toAidl(const V1_6::NetworkScanResult& res);
+
+::aidl::android::hardware::radio::network::SuppSvcNotification  //
+toAidl(const V1_0::SuppSvcNotification& svc);
+
+::aidl::android::hardware::radio::network::OperatorInfo toAidl(const V1_0::OperatorInfo& info);
+
+::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/network/utils.cpp b/radio/aidl/compat/libradiocompat/network/utils.cpp
new file mode 100644
index 0000000..6fe3e6e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/utils.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "utils.h"
+
+namespace android::hardware::radio::compat {
+
+namespace RAF {
+using E = V1_4::RadioAccessFamily;
+constexpr auto GSM = E::GSM | E::GPRS;
+constexpr auto CDMA = E::IS95A | E::IS95B | E::ONE_X_RTT;
+constexpr auto EVDO = E::EVDO_0 | E::EVDO_A | E::EVDO_B | E::EHRPD;
+constexpr auto HS = E::HSUPA | E::HSDPA | E::HSPA | E::HSPAP;
+constexpr auto WCDMA = HS | E::UMTS;
+constexpr auto LTE = E::LTE | E::LTE_CA;
+constexpr auto NR = E::NR;
+}  // namespace RAF
+
+static hidl_bitfield<V1_4::RadioAccessFamily>  //
+getAdjustedRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+    if (raf & RAF::GSM) raf |= RAF::GSM;
+    if (raf & RAF::WCDMA) raf |= RAF::WCDMA;
+    if (raf & RAF::CDMA) raf |= RAF::CDMA;
+    if (raf & RAF::EVDO) raf |= RAF::EVDO;
+    if (raf & RAF::LTE) raf |= RAF::LTE;
+    if (raf & RAF::NR) raf |= RAF::NR;
+
+    return raf;
+}
+
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+    raf = getAdjustedRaf(raf);
+    switch (raf) {
+        case RAF::GSM | RAF::WCDMA:
+            return V1_0::PreferredNetworkType::GSM_WCDMA_AUTO;
+        case RAF::GSM:
+            return V1_0::PreferredNetworkType::GSM_ONLY;
+        case RAF::WCDMA:
+            return V1_0::PreferredNetworkType::WCDMA;
+        case (RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::CDMA_EVDO_AUTO;
+        case (RAF::LTE | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::LTE_CDMA_EVDO;
+        case (RAF::LTE | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_GSM_WCDMA;
+        case (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA;  // CDMA typo
+        case RAF::LTE:
+            return V1_0::PreferredNetworkType::LTE_ONLY;
+        case (RAF::LTE | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_WCDMA;
+        case RAF::CDMA:
+            return V1_0::PreferredNetworkType::CDMA_ONLY;
+        case RAF::EVDO:
+            return V1_0::PreferredNetworkType::EVDO_ONLY;
+        case (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO;
+        case static_cast<int>(RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_ONLY;
+        case (RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA;
+        case (RAF::LTE | RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_LTE;
+        case (RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE;
+        case (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE;
+        case (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;
+        case static_cast<int>(RAF::NR):
+            return V1_0::PreferredNetworkType(23);  //  NR_ONLY
+        case (RAF::NR | RAF::LTE):
+            return V1_0::PreferredNetworkType(24);  //  NR_LTE
+        case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType(25);  //  NR_LTE_CDMA_EVDO
+        case (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(26);  //  NR_LTE_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(27);  //  NR_LTE_CDMA_EVDO_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(28);  //  NR_LTE_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType(29);  //  NR_LTE_TDSCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType(30);  //  NR_LTE_TDSCDMA_GSM
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(31);  //  NR_LTE_TDSCDMA_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(32);  //  NR_LTE_TDSCDMA_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+              RAF::WCDMA):
+            return V1_0::PreferredNetworkType(33);  //  NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+        default:
+            return V1_0::PreferredNetworkType::WCDMA;
+    }
+}
+
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type) {
+    switch (type) {
+        case V1_0::PreferredNetworkType::GSM_WCDMA_AUTO:
+            return RAF::GSM | RAF::WCDMA;
+        case V1_0::PreferredNetworkType::GSM_ONLY:
+            return RAF::GSM;
+        case V1_0::PreferredNetworkType::WCDMA:
+            return RAF::WCDMA;
+        case V1_0::PreferredNetworkType::CDMA_EVDO_AUTO:
+            return (RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::LTE_CDMA_EVDO:
+            return (RAF::LTE | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::LTE_GSM_WCDMA:
+            return (RAF::LTE | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA:
+            return (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::LTE_ONLY:
+            return RAF::LTE;
+        case V1_0::PreferredNetworkType::LTE_WCDMA:
+            return (RAF::LTE | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::CDMA_ONLY:
+            return RAF::CDMA;
+        case V1_0::PreferredNetworkType::EVDO_ONLY:
+            return RAF::EVDO;
+        case V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO:
+            return (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::TD_SCDMA_ONLY:
+            return static_cast<int>(RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA:
+            return (RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM:
+            return (RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA:
+            return (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO:
+            return (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+        case V1_0::PreferredNetworkType(23):  //  NR_ONLY
+            return static_cast<int>(RAF::NR);
+        case V1_0::PreferredNetworkType(24):  //  NR_LTE
+            return (RAF::NR | RAF::LTE);
+        case V1_0::PreferredNetworkType(25):  //  NR_LTE_CDMA_EVDO
+            return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType(26):  //  NR_LTE_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(27):  //  NR_LTE_CDMA_EVDO_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(28):  //  NR_LTE_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(29):  //  NR_LTE_TDSCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType(30):  //  NR_LTE_TDSCDMA_GSM
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType(31):  //  NR_LTE_TDSCDMA_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(32):  //  NR_LTE_TDSCDMA_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(33):  //  NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+                    RAF::WCDMA);
+#pragma GCC diagnostic pop
+        default:
+            return {};  // unknown
+    }
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/radio/aidl/compat/libradiocompat/network/utils.h
similarity index 63%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to radio/aidl/compat/libradiocompat/network/utils.h
index 46a9b1a..10714be 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/radio/aidl/compat/libradiocompat/network/utils.h
@@ -13,15 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#pragma once
 
-package android.hardware.radio.voice;
+#include <android/hardware/radio/1.4/types.h>
 
-import android.hardware.radio.voice.CdmaInformationRecord;
+namespace android::hardware::radio::compat {
 
-@VintfStability
-parcelable CdmaInformationRecords {
-    /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
-     */
-    CdmaInformationRecord[] infoRec;
-}
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf);
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
new file mode 100644
index 0000000..6b906c6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioSimIndication> simCb) {
+    CHECK(simCb);
+    mSimCb = simCb;
+}
+
+Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->carrierInfoForImsiEncryption(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
+        V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
+    return {};
+}
+
+Return<void> RadioIndication::simPhonebookChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simPhonebookChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::simPhonebookRecordsReceived(
+        V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+        const hidl_vec<V1_6::PhonebookRecordInfo>& rec) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
+    return {};
+}
+
+Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
+                                         const V1_0::SimRefreshResult& refreshResult) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simRefresh(toAidl(type), toAidl(refreshResult));
+    return {};
+}
+
+Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simStatusChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
+                                             const hidl_string& cmd) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkEventNotify(toAidl(type), cmd);
+    return {};
+}
+
+Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
+                                                  const hidl_string& cmd) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkProactiveCommand(toAidl(type), cmd);
+    return {};
+}
+
+Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkSessionEnd(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
+                                                        bool activate) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->subscriptionStatusChanged(toAidl(type), activate);
+    return {};
+}
+
+Return<void> RadioIndication::uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+                                                                bool enabled) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->uiccApplicationsEnablementChanged(toAidl(type), enabled);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
new file mode 100644
index 0000000..2dfbc50
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioSimResponse> simCb) {
+    CHECK(simCb);
+    mSimCb = simCb;
+}
+
+Return<void> RadioResponse::areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+                                                               bool enabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
+    return {};
+}
+
+Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->changeIccPinForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->enableUiccApplicationsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse(  //
+        const V1_0::RadioResponseInfo& info, bool allAllowed, const V1_0::CarrierRestrictions& cr) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    aidl::CarrierRestrictions aidlCr = toAidl(cr);
+    if (allAllowed) aidlCr = {};
+    mSimCb->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
+    return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
+        V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
+                                       aidl::SimLockMultiSimPolicy(multiSimPolicy));
+    return {};
+}
+
+Return<void> RadioResponse::getCDMASubscriptionResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+        const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+                                                              V1_0::CdmaSubscriptionSource s) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
+    return {};
+}
+
+Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t response) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getFacilityLockForAppResponse(toAidl(info), response);
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                         const V1_2::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                         const V1_4::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                         const V1_5::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                  const hidl_string& imsi) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getImsiForAppResponse(toAidl(info), imsi);
+    return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookCapacityResponse(
+        const V1_6::RadioResponseInfo& info, const V1_6::PhonebookCapacity& capacity) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
+    return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getSimPhonebookRecordsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccCloseLogicalChannelResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::IccIoResult& iccIo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
+    return {};
+}
+
+Return<void> RadioResponse::iccOpenLogicalChannelResponse(  //
+        const V1_0::RadioResponseInfo& info, int32_t chanId, const hidl_vec<int8_t>& selectResp) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
+    return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->reportStkServiceIsRunningResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                              const hidl_string&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "requestIsimAuthenticationResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+                                                 const hidl_string& commandResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendEnvelopeResponse(toAidl(info), commandResponse);
+    return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                           const V1_0::IccIoResult& iccIo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
+    return {};
+}
+
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendTerminalResponseToSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t numAllowed) {
+    LOG_CALL << info.serial << ' ' << numAllowed;
+    CHECK_CB(mSimCb);
+    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setCdmaSubscriptionSourceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t retry) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setFacilityLockForAppResponse(toAidl(info), retry);
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setUiccSubscriptionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                               V1_5::PersoSubstate persoType,
+                                                               int32_t rRet) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
+    return {};
+}
+
+Return<void> RadioResponse::updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+                                                              int32_t updatedRecordIndex) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
new file mode 100644
index 0000000..ca27918
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioSim.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Sim"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::sim;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->areUiccApplicationsEnabled(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+                                            const std::string& newPin2, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->changeIccPin2ForApp(serial, oldPin2, newPin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPinForApp(int32_t serial, const std::string& oldPin,
+                                           const std::string& newPin, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->changeIccPinForApp(serial, oldPin, newPin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::enableUiccApplications(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->enableUiccApplications(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAllowedCarriers(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscription(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCDMASubscription(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscriptionSource(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaSubscriptionSource(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getFacilityLockForApp(  //
+        int32_t serial, const std::string& facility, const std::string& password,
+        int32_t serviceClass, const std::string& appId) {
+    LOG_CALL << serial;
+    mHal1_5->getFacilityLockForApp(serial, facility, password, serviceClass, appId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getIccCardStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getIccCardStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getImsiForApp(int32_t serial, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->getImsiForApp(serial, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookCapacity(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSimPhonebookCapacity(serial);
+    } else {
+        respond().getSimPhonebookCapacityResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookRecords(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSimPhonebookRecords(serial);
+    } else {
+        respond().getSimPhonebookRecordsResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
+    LOG_CALL << serial;
+    mHal1_5->iccCloseLogicalChannel(serial, channelId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
+    LOG_CALL << serial;
+    mHal1_5->iccIOForApp(serial, toHidl(iccIo));
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccOpenLogicalChannel(int32_t serial, const std::string& aid, int32_t p2) {
+    LOG_CALL << serial;
+    mHal1_5->iccOpenLogicalChannel(serial, aid, p2);
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduBasicChannel(int32_t serial, const aidl::SimApdu& message) {
+    LOG_CALL << serial;
+    mHal1_5->iccTransmitApduBasicChannel(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduLogicalChannel(int32_t serial,
+                                                      const aidl::SimApdu& message) {
+    LOG_CALL << serial;
+    mHal1_5->iccTransmitApduLogicalChannel(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioSim::reportStkServiceIsRunning(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->reportStkServiceIsRunning(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::requestIccSimAuthentication(  //
+        int32_t serial, int32_t authContext, const std::string& authData, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->requestIccSimAuthentication(serial, authContext, authData, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelope(int32_t serial, const std::string& command) {
+    LOG_CALL << serial;
+    mHal1_5->sendEnvelope(serial, command);
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelopeWithStatus(int32_t serial, const std::string& contents) {
+    LOG_CALL << serial;
+    mHal1_5->sendEnvelopeWithStatus(serial, contents);
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendTerminalResponseToSim(int32_t serial,
+                                                  const std::string& commandResponse) {
+    LOG_CALL << serial;
+    mHal1_5->sendTerminalResponseToSim(serial, commandResponse);
+    return ok();
+}
+
+ScopedAStatus RadioSim::setAllowedCarriers(  //
+        int32_t serial, const aidl::CarrierRestrictions& carriers, aidl::SimLockMultiSimPolicy mp) {
+    LOG_CALL << serial;
+    mHal1_5->setAllowedCarriers_1_4(serial, toHidl(carriers), V1_4::SimLockMultiSimPolicy(mp));
+    return ok();
+}
+
+ScopedAStatus RadioSim::setCarrierInfoForImsiEncryption(
+        int32_t serial, const aidl::ImsiEncryptionInfo& imsiEncryptionInfo) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setCarrierInfoForImsiEncryption_1_6(serial, toHidl_1_6(imsiEncryptionInfo));
+    } else {
+        mHal1_5->setCarrierInfoForImsiEncryption(serial, toHidl(imsiEncryptionInfo));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::setCdmaSubscriptionSource(int32_t serial,
+                                                  aidl::CdmaSubscriptionSource cdmaSub) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaSubscriptionSource(serial, V1_0::CdmaSubscriptionSource(cdmaSub));
+    return ok();
+}
+
+ScopedAStatus RadioSim::setFacilityLockForApp(  //
+        int32_t serial, const std::string& facility, bool lockState, const std::string& password,
+        int32_t serviceClass, const std::string& appId) {
+    LOG_CALL << serial;
+    mHal1_5->setFacilityLockForApp(serial, facility, lockState, password, serviceClass, appId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioSimResponse>& simResponse,
+        const std::shared_ptr<aidl::IRadioSimIndication>& simIndication) {
+    LOG_CALL << simResponse << ' ' << simIndication;
+
+    CHECK(simResponse);
+    CHECK(simIndication);
+
+    mRadioResponse->setResponseFunction(simResponse);
+    mRadioIndication->setResponseFunction(simIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioSim::setSimCardPower(int32_t serial, aidl::CardPowerState powerUp) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setSimCardPower_1_6(serial, V1_1::CardPowerState(powerUp));
+    } else {
+        mHal1_5->setSimCardPower_1_1(serial, V1_1::CardPowerState(powerUp));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::setUiccSubscription(int32_t serial, const aidl::SelectUiccSub& uiccSub) {
+    LOG_CALL << serial;
+    mHal1_5->setUiccSubscription(serial, toHidl(uiccSub));
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+                                            const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPin2ForApp(serial, pin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPinForApp(int32_t serial, const std::string& pin,
+                                           const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPinForApp(serial, pin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+                                            const std::string& pin2, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPuk2ForApp(serial, puk2, pin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPukForApp(int32_t serial, const std::string& puk,
+                                           const std::string& pin, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPukForApp(serial, puk, pin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplySimDepersonalization(int32_t serial, aidl::PersoSubstate pss,
+                                                   const std::string& controlKey) {
+    LOG_CALL << serial;
+    mHal1_5->supplySimDepersonalization(serial, V1_5::PersoSubstate(pss), controlKey);
+    return ok();
+}
+
+ScopedAStatus RadioSim::updateSimPhonebookRecords(int32_t serial,
+                                                  const aidl::PhonebookRecordInfo& recordInfo) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->updateSimPhonebookRecords(serial, toHidl(recordInfo));
+    } else {
+        respond().updateSimPhonebookRecordsResponse(notSupported(serial), 0);
+    }
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
new file mode 100644
index 0000000..97a21a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+V1_0::IccIo toHidl(const aidl::IccIo& icc) {
+    return {
+            .command = icc.command,
+            .fileId = icc.fileId,
+            .path = icc.path,
+            .p1 = icc.p1,
+            .p2 = icc.p2,
+            .p3 = icc.p3,
+            .data = icc.data,
+            .pin2 = icc.pin2,
+            .aid = icc.aid,
+    };
+}
+
+V1_0::SimApdu toHidl(const aidl::SimApdu& apdu) {
+    return {
+            .sessionId = apdu.sessionId,
+            .cla = apdu.cla,
+            .instruction = apdu.instruction,
+            .p1 = apdu.p1,
+            .p2 = apdu.p2,
+            .p3 = apdu.p3,
+            .data = apdu.data,
+    };
+}
+
+aidl::Carrier toAidl(const V1_0::Carrier& carrier) {
+    return {
+            .mcc = carrier.mcc,
+            .mnc = carrier.mnc,
+            .matchType = static_cast<int32_t>(carrier.matchType),
+            .matchData = carrier.matchData,
+    };
+}
+
+V1_0::Carrier toHidl(const aidl::Carrier& carrier) {
+    return {
+            .mcc = carrier.mcc,
+            .mnc = carrier.mnc,
+            .matchType = V1_0::CarrierMatchType{carrier.matchType},
+            .matchData = carrier.matchData,
+    };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_0::CarrierRestrictions& cr) {
+    return {
+            .allowedCarriers = toAidl(cr.allowedCarriers),
+            .excludedCarriers = toAidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = true,
+    };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_4::CarrierRestrictionsWithPriority& cr) {
+    return {
+            .allowedCarriers = toAidl(cr.allowedCarriers),
+            .excludedCarriers = toAidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+    };
+}
+
+V1_4::CarrierRestrictionsWithPriority toHidl(const aidl::CarrierRestrictions& cr) {
+    return {
+            .allowedCarriers = toHidl(cr.allowedCarriers),
+            .excludedCarriers = toHidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+    };
+}
+
+V1_1::ImsiEncryptionInfo toHidl(const aidl::ImsiEncryptionInfo& info) {
+    return {
+            .mcc = info.mcc,
+            .mnc = info.mnc,
+            .carrierKey = info.carrierKey,
+            .keyIdentifier = info.keyIdentifier,
+            .expirationTime = info.expirationTime,
+    };
+}
+
+V1_6::ImsiEncryptionInfo toHidl_1_6(const aidl::ImsiEncryptionInfo& info) {
+    return {
+            .base = toHidl(info),
+            .keyType = V1_6::PublicKeyType{info.keyType},
+    };
+}
+
+V1_0::SelectUiccSub toHidl(const aidl::SelectUiccSub& sub) {
+    return {
+            .slot = sub.slot,
+            .appIndex = sub.appIndex,
+            .subType = {},
+            .actStatus = {},
+    };
+}
+
+aidl::PhonebookRecordInfo toAidl(const V1_6::PhonebookRecordInfo& info) {
+    return {
+            .recordId = static_cast<int32_t>(info.recordId),
+            .name = info.name,
+            .number = info.number,
+            .emails = toAidl(info.emails),
+            .additionalNumbers = toAidl(info.additionalNumbers),
+    };
+}
+
+V1_6::PhonebookRecordInfo toHidl(const aidl::PhonebookRecordInfo& info) {
+    return {
+            .recordId = static_cast<uint32_t>(info.recordId),
+            .name = info.name,
+            .number = info.number,
+            .emails = toHidl(info.emails),
+            .additionalNumbers = toHidl(info.additionalNumbers),
+    };
+}
+
+aidl::SimRefreshResult toAidl(const V1_0::SimRefreshResult& res) {
+    return {
+            .type = static_cast<int32_t>(res.type),
+            .efId = res.efId,
+            .aid = res.aid,
+    };
+}
+
+aidl::CardStatus toAidl(const V1_0::CardStatus& status) {
+    return toAidl(V1_2::CardStatus{status, 0, "", ""});
+}
+
+aidl::CardStatus toAidl(const V1_2::CardStatus& status) {
+    return toAidl(V1_4::CardStatus{status, ""});
+}
+
+aidl::CardStatus toAidl(const V1_4::CardStatus& status) {
+    auto aidlStatus = toAidl(V1_5::CardStatus{status, {}});
+    aidlStatus.applications = toAidl(status.base.base.applications);
+    return aidlStatus;
+}
+
+aidl::CardStatus toAidl(const V1_5::CardStatus& status) {
+    return {
+            .cardState = static_cast<int32_t>(status.base.base.base.cardState),
+            .universalPinState = aidl::PinState(status.base.base.base.universalPinState),
+            .gsmUmtsSubscriptionAppIndex = status.base.base.base.gsmUmtsSubscriptionAppIndex,
+            .cdmaSubscriptionAppIndex = status.base.base.base.cdmaSubscriptionAppIndex,
+            .imsSubscriptionAppIndex = status.base.base.base.imsSubscriptionAppIndex,
+            .applications = toAidl(status.applications),
+            .atr = status.base.base.atr,
+            .iccid = status.base.base.iccid,
+            .eid = status.base.eid,
+            // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
+            .slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
+    };
+}
+
+aidl::AppStatus toAidl(const V1_0::AppStatus& status) {
+    return toAidl({status, V1_5::PersoSubstate(status.persoSubstate)});
+}
+
+aidl::AppStatus toAidl(const V1_5::AppStatus& status) {
+    return {
+            .appType = static_cast<int32_t>(status.base.appType),
+            .appState = static_cast<int32_t>(status.base.appState),
+            .persoSubstate = aidl::PersoSubstate(status.persoSubstate),
+            .aidPtr = status.base.aidPtr,
+            .appLabelPtr = status.base.appLabelPtr,
+            .pin1Replaced = (status.base.pin1Replaced != 0),
+            .pin1 = aidl::PinState(status.base.pin1),
+            .pin2 = aidl::PinState(status.base.pin2),
+    };
+}
+
+aidl::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c) {
+    return {
+            .maxAdnRecords = c.maxAdnRecords,
+            .usedAdnRecords = c.usedAdnRecords,
+            .maxEmailRecords = c.maxEmailRecords,
+            .usedEmailRecords = c.usedEmailRecords,
+            .maxAdditionalNumberRecords = c.maxAdditionalNumberRecords,
+            .usedAdditionalNumberRecords = c.usedAdditionalNumberRecords,
+            .maxNameLen = c.maxNameLen,
+            .maxNumberLen = c.maxNumberLen,
+            .maxEmailLen = c.maxEmailLen,
+            .maxAdditionalNumberLen = c.maxAdditionalNumberLen,
+    };
+}
+
+aidl::IccIoResult toAidl(const V1_0::IccIoResult& iir) {
+    return {
+            .sw1 = iir.sw1,
+            .sw2 = iir.sw2,
+            .simResponse = iir.simResponse,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.h b/radio/aidl/compat/libradiocompat/sim/structs.h
new file mode 100644
index 0000000..54099b7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/sim/AppStatus.h>
+#include <aidl/android/hardware/radio/sim/CardStatus.h>
+#include <aidl/android/hardware/radio/sim/Carrier.h>
+#include <aidl/android/hardware/radio/sim/CarrierRestrictions.h>
+#include <aidl/android/hardware/radio/sim/IccIo.h>
+#include <aidl/android/hardware/radio/sim/IccIoResult.h>
+#include <aidl/android/hardware/radio/sim/ImsiEncryptionInfo.h>
+#include <aidl/android/hardware/radio/sim/PhonebookCapacity.h>
+#include <aidl/android/hardware/radio/sim/PhonebookRecordInfo.h>
+#include <aidl/android/hardware/radio/sim/SelectUiccSub.h>
+#include <aidl/android/hardware/radio/sim/SimApdu.h>
+#include <aidl/android/hardware/radio/sim/SimRefreshResult.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::IccIo toHidl(const ::aidl::android::hardware::radio::sim::IccIo& icc);
+
+V1_0::SimApdu toHidl(const ::aidl::android::hardware::radio::sim::SimApdu& apdu);
+
+::aidl::android::hardware::radio::sim::Carrier toAidl(const V1_0::Carrier& carrier);
+V1_0::Carrier toHidl(const ::aidl::android::hardware::radio::sim::Carrier& carrier);
+
+::aidl::android::hardware::radio::sim::CarrierRestrictions  //
+toAidl(const V1_0::CarrierRestrictions& cr);
+::aidl::android::hardware::radio::sim::CarrierRestrictions  //
+toAidl(const V1_4::CarrierRestrictionsWithPriority& cr);
+V1_4::CarrierRestrictionsWithPriority  //
+toHidl(const ::aidl::android::hardware::radio::sim::CarrierRestrictions& cr);
+
+V1_1::ImsiEncryptionInfo  //
+toHidl(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+V1_6::ImsiEncryptionInfo  //
+toHidl_1_6(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+
+V1_0::SelectUiccSub toHidl(const ::aidl::android::hardware::radio::sim::SelectUiccSub& sub);
+
+::aidl::android::hardware::radio::sim::PhonebookRecordInfo  //
+toAidl(const V1_6::PhonebookRecordInfo& info);
+V1_6::PhonebookRecordInfo  //
+toHidl(const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& info);
+
+::aidl::android::hardware::radio::sim::SimRefreshResult  //
+toAidl(const V1_0::SimRefreshResult& res);
+
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_0::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_2::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_4::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_5::CardStatus& status);
+
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_0::AppStatus& status);
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_5::AppStatus& status);
+
+::aidl::android::hardware::radio::sim::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c);
+
+::aidl::android::hardware::radio::sim::IccIoResult toAidl(const V1_0::IccIoResult& iir);
+
+}  // 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
new file mode 100644
index 0000000..6d9bda8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceIndication> voiceCb) {
+    CHECK(voiceCb);
+    mVoiceCb = voiceCb;
+}
+
+Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
+                                       const V1_0::CdmaSignalInfoRecord& record) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->callRing(toAidl(type), isGsm, toAidl(record));
+    return {};
+}
+
+Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->callStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
+                                              const V1_0::CdmaCallWaiting& callWaitingRecord) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
+                                          const V1_0::CdmaInformationRecords& records) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+                                                     V1_0::CdmaOtaProvisionStatus status) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
+    return {};
+}
+
+Return<void> RadioIndication::currentEmergencyNumberList(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::EmergencyNumber>& emergencyNumbers) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
+    return {};
+}
+
+Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->enterEmergencyCallbackMode(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->exitEmergencyCallbackMode(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->indicateRingbackTone(toAidl(type), start);
+    return {};
+}
+
+Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+                                                               const V1_0::StkCcUnsolSsResult& ss) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
+    return {};
+}
+
+Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->resendIncallMute(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
+                                               V1_0::SrvccState state) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
+    return {};
+}
+
+Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+                                                        const hidl_string& alpha) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stkCallControlAlphaNotify(toAidl(type), alpha);
+    return {};
+}
+
+Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stkCallSetup(toAidl(type), timeout);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
new file mode 100644
index 0000000..0a64c56
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceResponse> voiceCb) {
+    CHECK(voiceCb);
+    mVoiceCb = voiceCb;
+}
+
+Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->acceptCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->conferenceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->dialResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->emergencyDialResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->exitEmergencyCallbackModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->explicitCallTransferResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getCallForwardStatusResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::CallForwardInfo>& callFwdInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+                                                   int32_t serviceClass) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCallWaitingResponse(toAidl(info), enable, serviceClass);
+    return {};
+}
+
+Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
+                                            V1_0::ClipStatus status) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getClipResponse(toAidl(info), aidl::ClipStatus(status));
+    return {};
+}
+
+Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+                                            int32_t m) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getClirResponse(toAidl(info), n, m);
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_6::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getLastCallFailCauseResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
+    return {};
+}
+
+Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getMuteResponse(toAidl(info), enable);
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+                                                             bool enable) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getPreferredVoicePrivacyResponse(toAidl(info), enable);
+    return {};
+}
+
+Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+                                               V1_0::TtyMode mode) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
+    return {};
+}
+
+Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->handleStkCallSetupRequestFromSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupConnectionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupForegroundResumeBackgroundResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupWaitingOrBackgroundResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->rejectCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendBurstDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendCdmaFeatureCodeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->separateConnectionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setCallForwardResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setCallWaitingResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setClirResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setMuteResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setPreferredVoicePrivacyResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setTtyModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->startDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stopDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
new file mode 100644
index 0000000..16c6b14
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioVoice.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Voice"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::voice;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioVoice::acceptCall(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->acceptCall(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::conference(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->conference(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::dial(int32_t serial, const aidl::Dial& dialInfo) {
+    LOG_CALL << serial;
+    mHal1_5->dial(serial, toHidl(dialInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::emergencyDial(  //
+        int32_t serial, const aidl::Dial& dialInfo, aidl::EmergencyServiceCategory categories,
+        const std::vector<std::string>& urns, aidl::EmergencyCallRouting routing,
+        bool hasKnownUserIntentEmerg, bool isTesting) {
+    LOG_CALL << serial;
+    mHal1_5->emergencyDial(serial, toHidl(dialInfo),
+                           toHidlBitfield<V1_4::EmergencyServiceCategory>(categories), toHidl(urns),
+                           V1_4::EmergencyCallRouting(routing), hasKnownUserIntentEmerg, isTesting);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::exitEmergencyCallbackMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->exitEmergencyCallbackMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::explicitCallTransfer(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->explicitCallTransfer(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCallForwardStatus(int32_t serial,
+                                               const aidl::CallForwardInfo& callInfo) {
+    LOG_CALL << serial;
+    mHal1_5->getCallForwardStatus(serial, toHidl(callInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCallWaiting(int32_t serial, int32_t serviceClass) {
+    LOG_CALL << serial;
+    mHal1_5->getCallWaiting(serial, serviceClass);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getClip(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getClip(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getClir(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getClir(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCurrentCalls(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCurrentCalls(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getLastCallFailCause(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getLastCallFailCause(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getMute(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getMute(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getPreferredVoicePrivacy(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getPreferredVoicePrivacy(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getTtyMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getTTYMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
+    LOG_CALL << serial;
+    mHal1_5->handleStkCallSetupRequestFromSim(serial, accept);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangup(int32_t serial, int32_t gsmIndex) {
+    LOG_CALL << serial;
+    mHal1_5->hangup(serial, gsmIndex);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangupForegroundResumeBackground(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->hangupForegroundResumeBackground(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangupWaitingOrBackground(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->hangupWaitingOrBackground(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::isVoNrEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): can't call isVoNrEnabledResponse with 1.6 callback
+    return ok();
+}
+
+ScopedAStatus RadioVoice::rejectCall(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->rejectCall(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+                                        int32_t off) {
+    LOG_CALL << serial;
+    mHal1_5->sendBurstDtmf(serial, dtmf, on, off);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendCdmaFeatureCode(int32_t serial, const std::string& featureCode) {
+    LOG_CALL << serial;
+    mHal1_5->sendCDMAFeatureCode(serial, featureCode);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendDtmf(int32_t serial, const std::string& s) {
+    LOG_CALL << serial;
+    mHal1_5->sendDtmf(serial, s);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::separateConnection(int32_t serial, int32_t gsmIndex) {
+    LOG_CALL << serial;
+    mHal1_5->separateConnection(serial, gsmIndex);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setCallForward(int32_t serial, const aidl::CallForwardInfo& callInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setCallForward(serial, toHidl(callInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
+    LOG_CALL << serial;
+    mHal1_5->setCallWaiting(serial, enable, serviceClass);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setClir(int32_t serial, int32_t status) {
+    LOG_CALL << serial;
+    mHal1_5->setClir(serial, status);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setMute(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setMute(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setPreferredVoicePrivacy(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setPreferredVoicePrivacy(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioVoiceResponse>& voiceResponse,
+        const std::shared_ptr<aidl::IRadioVoiceIndication>& voiceIndication) {
+    LOG_CALL << voiceResponse << ' ' << voiceIndication;
+
+    CHECK(voiceResponse);
+    CHECK(voiceIndication);
+
+    mRadioResponse->setResponseFunction(voiceResponse);
+    mRadioIndication->setResponseFunction(voiceIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setTtyMode(int32_t serial, aidl::TtyMode mode) {
+    LOG_CALL << serial;
+    mHal1_5->setTTYMode(serial, V1_0::TtyMode(mode));
+    return ok();
+}
+
+ndk::ScopedAStatus RadioVoice::setVoNrEnabled(int32_t serial, [[maybe_unused]] bool enable) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): should set `persist.radio.is_vonr_enabled_` property instead
+    return ok();
+}
+
+ScopedAStatus RadioVoice::startDtmf(int32_t serial, const std::string& s) {
+    LOG_CALL << serial;
+    mHal1_5->startDtmf(serial, s);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::stopDtmf(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->stopDtmf(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::switchWaitingOrHoldingAndActive(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->switchWaitingOrHoldingAndActive(serial);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
new file mode 100644
index 0000000..ae6342e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+V1_0::Dial toHidl(const aidl::Dial& info) {
+    return {
+            .address = info.address,
+            .clir = V1_0::Clir{info.clir},
+            .uusInfo = toHidl(info.uusInfo),
+    };
+}
+
+V1_0::UusInfo toHidl(const aidl::UusInfo& info) {
+    return {
+            .uusType = V1_0::UusType{info.uusType},
+            .uusDcs = V1_0::UusDcs{info.uusDcs},
+            .uusData = info.uusData,
+    };
+}
+
+aidl::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info) {
+    return {
+            .status = static_cast<int32_t>(info.status),
+            .reason = info.reason,
+            .serviceClass = info.serviceClass,
+            .toa = info.toa,
+            .number = info.number,
+            .timeSeconds = info.timeSeconds,
+    };
+}
+
+V1_0::CallForwardInfo toHidl(const aidl::CallForwardInfo& info) {
+    return {
+            .status = V1_0::CallForwardInfoStatus{info.status},
+            .reason = info.reason,
+            .serviceClass = info.serviceClass,
+            .toa = info.toa,
+            .number = info.number,
+            .timeSeconds = info.timeSeconds,
+    };
+}
+
+aidl::CdmaSignalInfoRecord toAidl(const V1_0::CdmaSignalInfoRecord& record) {
+    return {
+            .isPresent = record.isPresent,
+            .signalType = record.signalType,
+            .alertPitch = record.alertPitch,
+            .signal = record.signal,
+    };
+}
+
+aidl::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call) {
+    return {
+            .number = call.number,
+            .numberPresentation = static_cast<int32_t>(call.numberPresentation),
+            .name = call.name,
+            .signalInfoRecord = toAidl(call.signalInfoRecord),
+            .numberType = static_cast<int32_t>(call.numberType),
+            .numberPlan = static_cast<int32_t>(call.numberPlan),
+    };
+}
+
+aidl::CdmaInformationRecord toAidl(const V1_0::CdmaInformationRecord& record) {
+    return {
+            .name = static_cast<int32_t>(record.name),
+            .display = toAidl(record.display),
+            .number = toAidl(record.number),
+            .signal = toAidl(record.signal),
+            .redir = toAidl(record.redir),
+            .lineCtrl = toAidl(record.lineCtrl),
+            .clir = toAidl(record.clir),
+            .audioCtrl = toAidl(record.audioCtrl),
+    };
+}
+
+aidl::CdmaDisplayInfoRecord toAidl(const V1_0::CdmaDisplayInfoRecord& record) {
+    return {
+            .alphaBuf = record.alphaBuf,
+    };
+}
+
+aidl::CdmaNumberInfoRecord toAidl(const V1_0::CdmaNumberInfoRecord& record) {
+    return {
+            .number = record.number,
+            .numberType = static_cast<int8_t>(record.numberType),
+            .numberPlan = static_cast<int8_t>(record.numberPlan),
+            .pi = static_cast<int8_t>(record.pi),
+            .si = static_cast<int8_t>(record.si),
+    };
+}
+
+aidl::CdmaRedirectingNumberInfoRecord toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record) {
+    return {
+            .redirectingNumber = toAidl(record.redirectingNumber),
+            .redirectingReason = static_cast<int32_t>(record.redirectingReason),
+    };
+}
+
+aidl::CdmaLineControlInfoRecord toAidl(const V1_0::CdmaLineControlInfoRecord& record) {
+    return {
+            .lineCtrlPolarityIncluded = static_cast<int8_t>(record.lineCtrlPolarityIncluded),
+            .lineCtrlToggle = static_cast<int8_t>(record.lineCtrlToggle),
+            .lineCtrlReverse = static_cast<int8_t>(record.lineCtrlReverse),
+            .lineCtrlPowerDenial = static_cast<int8_t>(record.lineCtrlPowerDenial),
+    };
+}
+
+aidl::CdmaT53ClirInfoRecord toAidl(const V1_0::CdmaT53ClirInfoRecord& record) {
+    return {
+            .cause = static_cast<int8_t>(record.cause),
+    };
+}
+
+aidl::CdmaT53AudioControlInfoRecord toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record) {
+    return {
+            .upLink = static_cast<int8_t>(record.upLink),
+            .downLink = static_cast<int8_t>(record.downLink),
+    };
+}
+
+aidl::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num) {
+    return {
+            .number = num.number,
+            .mcc = num.mcc,
+            .mnc = num.mnc,
+            .categories = aidl::EmergencyServiceCategory(num.categories),
+            .urns = toAidl(num.urns),
+            .sources = num.sources,
+    };
+}
+
+aidl::StkCcUnsolSsResult toAidl(const V1_0::StkCcUnsolSsResult& res) {
+    return {
+            .serviceType = static_cast<int32_t>(res.serviceType),
+            .requestType = static_cast<int32_t>(res.requestType),
+            .teleserviceType = static_cast<int32_t>(res.teleserviceType),
+            .serviceClass = res.serviceClass,
+            .result = toAidl(res.result),
+            .ssInfo = toAidl(res.ssInfo),
+            .cfData = toAidl(res.cfData),
+    };
+}
+
+aidl::SsInfoData toAidl(const V1_0::SsInfoData& info) {
+    return {
+            .ssInfo = info.ssInfo,
+    };
+}
+
+aidl::CfData toAidl(const V1_0::CfData& data) {
+    return {
+            .cfInfo = toAidl(data.cfInfo),
+    };
+}
+
+aidl::Call toAidl(const V1_0::Call& call) {
+    return toAidl(V1_2::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_2::Call& call) {
+    return toAidl(V1_6::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_6::Call& call) {
+    return {
+            .state = static_cast<int32_t>(call.base.base.state),
+            .index = call.base.base.index,
+            .toa = call.base.base.toa,
+            .isMpty = call.base.base.isMpty,
+            .isMT = call.base.base.isMT,
+            .als = static_cast<int8_t>(call.base.base.als),
+            .isVoice = call.base.base.isVoice,
+            .isVoicePrivacy = call.base.base.isVoicePrivacy,
+            .number = call.base.base.number,
+            .numberPresentation = static_cast<int32_t>(call.base.base.numberPresentation),
+            .name = call.base.base.name,
+            .namePresentation = static_cast<int32_t>(call.base.base.namePresentation),
+            .uusInfo = toAidl(call.base.base.uusInfo),
+            .audioQuality = aidl::AudioQuality(call.base.audioQuality),
+            .forwardedNumber = call.forwardedNumber,
+    };
+}
+
+aidl::UusInfo toAidl(const V1_0::UusInfo& info) {
+    return {
+            .uusType = static_cast<int32_t>(info.uusType),
+            .uusDcs = static_cast<int32_t>(info.uusDcs),
+            .uusData = info.uusData,
+    };
+}
+
+aidl::LastCallFailCauseInfo toAidl(const V1_0::LastCallFailCauseInfo& info) {
+    return {
+            .causeCode = aidl::LastCallFailCause(info.causeCode),
+            .vendorCause = info.vendorCause,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.h b/radio/aidl/compat/libradiocompat/voice/structs.h
new file mode 100644
index 0000000..b55a089
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/voice/Call.h>
+#include <aidl/android/hardware/radio/voice/CallForwardInfo.h>
+#include <aidl/android/hardware/radio/voice/CdmaCallWaiting.h>
+#include <aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaInformationRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CfData.h>
+#include <aidl/android/hardware/radio/voice/Dial.h>
+#include <aidl/android/hardware/radio/voice/EmergencyNumber.h>
+#include <aidl/android/hardware/radio/voice/LastCallFailCauseInfo.h>
+#include <aidl/android/hardware/radio/voice/SsInfoData.h>
+#include <aidl/android/hardware/radio/voice/StkCcUnsolSsResult.h>
+#include <aidl/android/hardware/radio/voice/UusInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::Dial toHidl(const ::aidl::android::hardware::radio::voice::Dial& info);
+
+V1_0::UusInfo toHidl(const ::aidl::android::hardware::radio::voice::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info);
+V1_0::CallForwardInfo toHidl(const ::aidl::android::hardware::radio::voice::CallForwardInfo& info);
+
+::aidl::android::hardware::radio::voice::CdmaSignalInfoRecord  //
+toAidl(const V1_0::CdmaSignalInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call);
+
+::aidl::android::hardware::radio::voice::CdmaInformationRecord  //
+toAidl(const V1_0::CdmaInformationRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaDisplayInfoRecord  //
+toAidl(const V1_0::CdmaDisplayInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaNumberInfoRecord  //
+toAidl(const V1_0::CdmaNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaRedirectingNumberInfoRecord  //
+toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaLineControlInfoRecord  //
+toAidl(const V1_0::CdmaLineControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53ClirInfoRecord  //
+toAidl(const V1_0::CdmaT53ClirInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53AudioControlInfoRecord  //
+toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num);
+
+::aidl::android::hardware::radio::voice::StkCcUnsolSsResult  //
+toAidl(const V1_0::StkCcUnsolSsResult& res);
+
+::aidl::android::hardware::radio::voice::SsInfoData toAidl(const V1_0::SsInfoData& info);
+
+::aidl::android::hardware::radio::voice::CfData toAidl(const V1_0::CfData& data);
+
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_0::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_2::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_6::Call& call);
+
+::aidl::android::hardware::radio::voice::UusInfo toAidl(const V1_0::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::LastCallFailCauseInfo  //
+toAidl(const V1_0::LastCallFailCauseInfo& info);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
new file mode 100644
index 0000000..52eb71f
--- /dev/null
+++ b/radio/aidl/compat/service/Android.bp
@@ -0,0 +1,64 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.radio-service.compat",
+    relative_install_path: "hw",
+    init_rc: ["radio-compat.rc"],
+    vintf_fragments: ["radio-compat.xml"],
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+    ],
+    shared_libs: [
+        "android.hardware.radio-library.compat",
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio@1.0",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.5",
+        "android.hardware.radio@1.6",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+    ],
+    srcs: [
+        "hidl-utils.cpp",
+        "service.cpp",
+    ],
+}
diff --git a/radio/aidl/compat/service/hidl-utils.cpp b/radio/aidl/compat/service/hidl-utils.cpp
new file mode 100644
index 0000000..fc0d54d
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+namespace android::hardware::hidl_utils {
+
+class HalDeathRecipient : public hidl_death_recipient {
+    void serviceDied(uint64_t /* cookie */, const wp<hidl::base::V1_0::IBase>& /* who */) override {
+        LOG(FATAL) << "One of the linked HALs died. Restarting...";
+    }
+};
+
+static const auto gHalDeathRecipient = sp<HalDeathRecipient>::make();
+
+void linkDeathToDeath(sp<::android::hidl::base::V1_0::IBase> hal) {
+    const auto linkStatus = hal->linkToDeath(gHalDeathRecipient, 0);
+    CHECK(linkStatus.withDefault(false)) << "Failed to link to HAL death";
+}
+
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor) {
+    auto manager = hidl::manager::V1_2::IServiceManager::getService();
+    hidl_vec<hidl_string> services;
+    manager->listManifestByInterface(descriptor, hidl_utils::fill(&services));
+    CHECK_GT(services.size(), 0u) << "No " << descriptor
+                                  << " services in manifest (missing privileges?)" << std::endl;
+    return services;
+}
+
+}  // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/hidl-utils.h b/radio/aidl/compat/service/hidl-utils.h
new file mode 100644
index 0000000..be3386f
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hidl/base/1.0/IBase.h>
+
+#include <functional>
+
+namespace android::hardware::hidl_utils {
+
+/**
+ * Helper functor to fetch results from multi-return HIDL calls.
+ * It's meant to be used in place of _hidl_cb callbacks.
+ *
+ * Please note extracting these return variables outside of the callback scope requires making
+ * a copy of each return variable. This may be costly for frequently called HIDL methods with
+ * non-negligible return object size. Please be cautious about performance when using this.
+ *
+ * Example usage:
+ *     Result result;
+ *     sp<ISomeInterface> iface;
+ *     hidlObject->someMethod(arg1, arg2, hidl_utils::fill(&result, &iface)).assertOk();
+ *     // use result and iface
+ */
+template <typename... T>
+struct fill : public std::function<void(const T&...)> {
+    /**
+     * Create _hidl_cb functor that copies the call arguments to specified pointers.
+     *
+     * \param args... Targets to copy the call arguments to
+     */
+    fill(T*... args) : mTargets(args...) {}
+
+    void operator()(const T&... args) { copy<0, T...>(args...); }
+
+  private:
+    std::tuple<T*...> mTargets;
+
+    template <int Pos, typename First>
+    inline void copy(const First& first) {
+        *std::get<Pos>(mTargets) = first;
+    }
+
+    template <int Pos, typename First, typename... Rest>
+    inline void copy(const First& first, const Rest&... rest) {
+        *std::get<Pos>(mTargets) = first;
+        copy<Pos + 1, Rest...>(rest...);
+    }
+};
+
+/**
+ * Link to a given HALs death and restart the current process in such a case.
+ * \param hal HAL to which death to link
+ */
+void linkDeathToDeath(sp<hidl::base::V1_0::IBase> hal);
+
+/**
+ * List HAL instances of a given interface.
+ *
+ * \descriptor HIDL HAL descriptor
+ */
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor);
+
+}  // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/radio-compat.rc b/radio/aidl/compat/service/radio-compat.rc
new file mode 100644
index 0000000..a159876
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.rc
@@ -0,0 +1,4 @@
+service vendor.radio-compat /vendor/bin/hw/android.hardware.radio-service.compat
+    class hal
+    user nobody
+    group system
diff --git a/radio/aidl/compat/service/radio-compat.xml b/radio/aidl/compat/service/radio-compat.xml
new file mode 100644
index 0000000..a7089e6
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.xml
@@ -0,0 +1,37 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.radio.config</name>
+        <fqname>IRadioConfig/default</fqname>
+    </hal>
+<!--
+    Instances other than config are configured per-device, depending on the slot count (framework
+    currently supports slot1, slot2 and slot3 instances) and Radio HALs device wishes to provide.
+    You can either copy the following tags to device manifest or simply uncomment them here for
+    quick testing.
+
+    <hal format="aidl">
+        <name>android.hardware.radio.data</name>
+        <fqname>IRadioData/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.messaging</name>
+        <fqname>IRadioMessaging/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.modem</name>
+        <fqname>IRadioModem/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.network</name>
+        <fqname>IRadioNetwork/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.sim</name>
+        <fqname>IRadioSim/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.voice</name>
+        <fqname>IRadioVoice/slot1</fqname>
+    </hal>
+-->
+</manifest>
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
new file mode 100644
index 0000000..2a67569
--- /dev/null
+++ b/radio/aidl/compat/service/service.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <libradiocompat/RadioConfig.h>
+#include <libradiocompat/RadioData.h>
+#include <libradiocompat/RadioIndication.h>
+#include <libradiocompat/RadioMessaging.h>
+#include <libradiocompat/RadioModem.h>
+#include <libradiocompat/RadioNetwork.h>
+#include <libradiocompat/RadioResponse.h>
+#include <libradiocompat/RadioSim.h>
+#include <libradiocompat/RadioVoice.h>
+
+namespace android::hardware::radio::service {
+
+using namespace std::string_literals;
+
+static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
+
+template <typename T>
+static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
+                            sp<compat::RadioIndication> indicationCb, const std::string& slot) {
+    const auto instance = T::descriptor + "/"s + slot;
+    if (!AServiceManager_isDeclared(instance.c_str())) {
+        LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)";
+        return;
+    }
+    LOG(DEBUG) << "Publishing " << instance;
+
+    auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+    gPublishedHals.push_back(aidlHal);
+    const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+}
+
+static void publishRadio(std::string slot) {
+    auto radioHidl = V1_5::IRadio::getService(slot);
+    CHECK(radioHidl) << "HIDL IRadio not present in VINTF";
+
+    hidl_utils::linkDeathToDeath(radioHidl);
+
+    auto responseCb = sp<compat::RadioResponse>::make();
+    auto indicationCb = sp<compat::RadioIndication>::make();
+    radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
+
+    publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+}
+
+static void publishRadioConfig() {
+    auto hidlHal = config::V1_1::IRadioConfig::getService();
+    CHECK(hidlHal) << "HIDL IRadioConfig not present in VINTF";
+
+    hidl_utils::linkDeathToDeath(hidlHal);
+
+    auto aidlHal = ndk::SharedRefBase::make<compat::RadioConfig>(hidlHal);
+    gPublishedHals.push_back(aidlHal);
+    const auto instance = compat::RadioConfig::descriptor + "/default"s;
+    const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+}
+
+static void main() {
+    base::SetDefaultTag("radiocompat");
+    base::SetMinimumLogSeverity(base::VERBOSE);
+    LOG(DEBUG) << "Radio HAL compat service starting...";
+
+    publishRadioConfig();
+
+    const auto slots = hidl_utils::listManifestByInterface(V1_0::IRadio::descriptor);
+    LOG(INFO) << "Found " << slots.size() << " slot(s)";
+    for (const auto& slot : slots) {
+        publishRadio(slot);
+    }
+
+    LOG(DEBUG) << "Radio HAL compat service is operational";
+    ABinderProcess_joinThreadPool();
+    LOG(FATAL) << "Radio HAL compat service has stopped";
+}
+
+}  // namespace android::hardware::radio::service
+
+int main() {
+    android::hardware::radio::service::main();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index 028d297..3cf6ff2 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -38,3 +38,30 @@
     },
     versions: ["1"],
 }
+
+// cc_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.
+cc_defaults {
+    name: "keymint_use_latest_hal_aidl_ndk_static",
+    static_libs: [
+        "android.hardware.security.keymint-V1-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "keymint_use_latest_hal_aidl_ndk_shared",
+    shared_libs: [
+        "android.hardware.security.keymint-V1-ndk",
+    ],
+}
+
+// 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.
+rust_defaults {
+    name: "keymint_use_latest_hal_aidl_rust",
+    rustlibs: [
+        "android.hardware.security.keymint-V1-rust",
+    ],
+}
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index c2918ef..1a17fd4 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -21,8 +21,10 @@
         "-Wall",
         "-Wextra",
     ],
+    defaults: [
+        "keymint_use_latest_hal_aidl_ndk_shared",
+    ],
     shared_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "android.hardware.security.sharedsecret-V1-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libbase",
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index ff6a6f8..2d2d701 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -26,6 +26,7 @@
 cc_defaults {
     name: "keymint_vts_defaults",
     defaults: [
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
         "VtsHalTargetTestDefaults",
     ],
@@ -34,7 +35,6 @@
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libcppcose_rkp",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 26ed344..73c3820 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -50,7 +50,7 @@
         vector<KeyCharacteristics> attest_key_characteristics;
         vector<Certificate> attest_key_cert_chain;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                     .RsaSigningKey(size, 65537)
+                                                     .RsaKey(size, 65537)
                                                      .AttestKey()
                                                      .SetDefaultValidity(),
                                              {} /* attestation signing key */, &attest_key.keyBlob,
@@ -200,7 +200,7 @@
     vector<Certificate> attest_key_cert_chain;
     ASSERT_EQ(ErrorCode::OK,
               GenerateKey(AuthorizationSetBuilder()
-                                  .RsaSigningKey(2048, 65537)
+                                  .RsaKey(2048, 65537)
                                   .AttestKey()
                                   .AttestationChallenge(challenge)
                                   .AttestationApplicationId(app_id)
@@ -299,7 +299,7 @@
 
         EXPECT_EQ(ErrorCode::OK,
                   GenerateKey(AuthorizationSetBuilder()
-                                      .RsaSigningKey(2048, 65537)
+                                      .RsaKey(2048, 65537)
                                       .AttestKey()
                                       .AttestationChallenge("foo")
                                       .AttestationApplicationId("bar")
@@ -371,7 +371,7 @@
 
         EXPECT_EQ(ErrorCode::OK,
                   GenerateKey(AuthorizationSetBuilder()
-                                      .EcdsaSigningKey(EcCurve::P_256)
+                                      .EcdsaKey(EcCurve::P_256)
                                       .AttestKey()
                                       .AttestationChallenge("foo")
                                       .AttestationApplicationId("bar")
@@ -446,7 +446,7 @@
         if ((i & 0x1) == 1) {
             EXPECT_EQ(ErrorCode::OK,
                       GenerateKey(AuthorizationSetBuilder()
-                                          .EcdsaSigningKey(EcCurve::P_256)
+                                          .EcdsaKey(EcCurve::P_256)
                                           .AttestKey()
                                           .AttestationChallenge("foo")
                                           .AttestationApplicationId("bar")
@@ -459,7 +459,7 @@
         } else {
             EXPECT_EQ(ErrorCode::OK,
                       GenerateKey(AuthorizationSetBuilder()
-                                          .RsaSigningKey(2048, 65537)
+                                          .RsaKey(2048, 65537)
                                           .AttestKey()
                                           .AttestationChallenge("foo")
                                           .AttestationApplicationId("bar")
@@ -509,7 +509,7 @@
         vector<KeyCharacteristics> attest_key_characteristics;
         vector<Certificate> attest_key_cert_chain;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                     .RsaSigningKey(size, 65537)
+                                                     .RsaKey(size, 65537)
                                                      .AttestKey()
                                                      .SetDefaultValidity(),
                                              {} /* attestation signing key */, &attest_key.keyBlob,
@@ -555,12 +555,12 @@
         AttestationKey attest_key;
         vector<KeyCharacteristics> attest_key_characteristics;
         vector<Certificate> attest_key_cert_chain;
-        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                     .EcdsaSigningKey(curve)
-                                                     .AttestKey()
-                                                     .SetDefaultValidity(),
-                                             {} /* attestation signing key */, &attest_key.keyBlob,
-                                             &attest_key_characteristics, &attest_key_cert_chain));
+        ASSERT_EQ(
+                ErrorCode::OK,
+                GenerateKey(
+                        AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(),
+                        {} /* attestation signing key */, &attest_key.keyBlob,
+                        &attest_key_characteristics, &attest_key_cert_chain));
 
         ASSERT_GT(attest_key_cert_chain.size(), 0);
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -583,6 +583,7 @@
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
 
+        ASSERT_GT(attested_key_cert_chain.size(), 0);
         CheckedDeleteKey(&attested_key_blob);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
@@ -612,6 +613,7 @@
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
 
+        ASSERT_GT(attested_key_cert_chain.size(), 0);
         CheckedDeleteKey(&attested_key_blob);
         CheckedDeleteKey(&attest_key.keyBlob);
 
@@ -671,7 +673,7 @@
     vector<KeyCharacteristics> attest_key_characteristics;
     vector<Certificate> attest_key_cert_chain;
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .EcdsaSigningKey(EcCurve::P_256)
+                                                 .EcdsaKey(EcCurve::P_256)
                                                  .AttestKey()
                                                  .SetDefaultValidity(),
                                          {} /* attestation signing key */, &attest_key.keyBlob,
@@ -735,7 +737,7 @@
     vector<KeyCharacteristics> attest_key_characteristics;
     vector<Certificate> attest_key_cert_chain;
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .EcdsaSigningKey(EcCurve::P_256)
+                                                 .EcdsaKey(EcCurve::P_256)
                                                  .AttestKey()
                                                  .SetDefaultValidity(),
                                          {} /* attestation signing key */, &attest_key.keyBlob,
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 6f2f189..3cbffbf 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -78,6 +78,7 @@
                                       .Digest(Digest::SHA_2_256)
                                       .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -106,6 +107,7 @@
                                       .EcdsaSigningKey(EcCurve::P_256)
                                       .Digest(Digest::SHA_2_256)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -135,6 +137,7 @@
                                       .Digest(Digest::SHA_2_256)
                                       .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -192,6 +195,7 @@
                                       .EcdsaSigningKey(EcCurve::P_256)
                                       .Digest(Digest::SHA_2_256)
                                       .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
                                       .AttestationChallenge("challenge")
                                       .AttestationApplicationId("foo")
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -252,14 +256,16 @@
 
     for (const KeyParameter& tag : attestation_id_tags) {
         SCOPED_TRACE(testing::Message() << "+tag-" << tag);
-        AuthorizationSetBuilder builder = AuthorizationSetBuilder()
-                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                  .EcdsaSigningKey(EcCurve::P_256)
-                                                  .Digest(Digest::SHA_2_256)
-                                                  .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                                  .AttestationChallenge("challenge")
-                                                  .AttestationApplicationId("foo")
-                                                  .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .EcdsaSigningKey(EcCurve::P_256)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                        .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                        .AttestationChallenge("challenge")
+                        .AttestationApplicationId("foo")
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
         builder.push_back(tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
 
@@ -322,14 +328,16 @@
 
     for (const KeyParameter& invalid_tag : attestation_id_tags) {
         SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
-        AuthorizationSetBuilder builder = AuthorizationSetBuilder()
-                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                  .EcdsaSigningKey(EcCurve::P_256)
-                                                  .Digest(Digest::SHA_2_256)
-                                                  .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                                  .AttestationChallenge("challenge")
-                                                  .AttestationApplicationId("foo")
-                                                  .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .EcdsaSigningKey(EcCurve::P_256)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                        .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                        .AttestationChallenge("challenge")
+                        .AttestationApplicationId("foo")
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
         // Add the tag that doesn't match the local device's real ID.
         builder.push_back(invalid_tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 12ce859..6140df1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1067,6 +1067,8 @@
         }
     } else {
         switch (algorithm) {
+            case Algorithm::AES:
+                return {64, 96, 131, 512};
             case Algorithm::TRIPLE_DES:
                 return {56};
             default:
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 95e25d6..c99e1d0 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -69,8 +69,11 @@
 
 namespace {
 
+// Whether to check that BOOT_PATCHLEVEL is populated.
+bool check_boot_pl = true;
+
 // The maximum number of times we'll attempt to verify that corruption
-// of an ecrypted blob results in an error. Retries are necessary as there
+// of an encrypted blob results in an error. Retries are necessary as there
 // is a small (roughly 1/256) chance that corrupting ciphertext still results
 // in valid PKCS7 padding.
 constexpr size_t kMaxPaddingCorruptionRetries = 8;
@@ -527,12 +530,17 @@
         EXPECT_TRUE(os_pl);
         EXPECT_EQ(*os_pl, os_patch_level());
 
-        // Should include vendor and boot patchlevels.
+        // Should include vendor patchlevel.
         auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
         EXPECT_TRUE(vendor_pl);
         EXPECT_EQ(*vendor_pl, vendor_patch_level());
-        auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
-        EXPECT_TRUE(boot_pl);
+
+        // Should include boot patchlevel (but there are some test scenarios where this is not
+        // possible).
+        if (check_boot_pl) {
+            auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+            EXPECT_TRUE(boot_pl);
+        }
 
         return auths;
     }
@@ -1627,13 +1635,13 @@
  */
 TEST_P(NewKeyGenerationTest, EcdsaAttestationUniqueId) {
     auto get_unique_id = [this](const std::string& app_id, uint64_t datetime,
-                                vector<uint8_t>* unique_id) {
+                                vector<uint8_t>* unique_id, bool reset = false) {
         auto challenge = "hello";
         auto subject = "cert subj 2";
         vector<uint8_t> subject_der(make_name_from_str(subject));
         uint64_t serial_int = 0x1010;
         vector<uint8_t> serial_blob(build_serial_blob(serial_int));
-        const AuthorizationSetBuilder builder =
+        AuthorizationSetBuilder builder =
                 AuthorizationSetBuilder()
                         .Authorization(TAG_NO_AUTH_REQUIRED)
                         .Authorization(TAG_INCLUDE_UNIQUE_ID)
@@ -1645,6 +1653,9 @@
                         .AttestationApplicationId(app_id)
                         .Authorization(TAG_CREATION_DATETIME, datetime)
                         .SetDefaultValidity();
+        if (reset) {
+            builder.Authorization(TAG_RESET_SINCE_ID_ROTATION);
+        }
 
         ASSERT_EQ(ErrorCode::OK, GenerateKey(builder));
         ASSERT_GT(key_blob_.size(), 0U);
@@ -1706,6 +1717,11 @@
     vector<uint8_t> unique_id8;
     get_unique_id(app_id, min_date - 1, &unique_id8);
     EXPECT_NE(unique_id, unique_id8);
+
+    // Marking RESET_SINCE_ID_ROTATION should give a different unique ID.
+    vector<uint8_t> unique_id9;
+    get_unique_id(app_id, cert_date, &unique_id9, /* reset_id = */ true);
+    EXPECT_NE(unique_id, unique_id9);
 }
 
 /*
@@ -6906,6 +6922,12 @@
             } else {
                 std::cout << "NOT dumping attestations" << std::endl;
             }
+            if (std::string(argv[i]) == "--skip_boot_pl_check") {
+                // Allow checks of BOOT_PATCHLEVEL to be disabled, so that the tests can
+                // be run in emulated environments that don't have the normal bootloader
+                // interactions.
+                aidl::android::hardware::security::keymint::test::check_boot_pl = false;
+            }
         }
     }
     return RUN_ALL_TESTS();
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 355f87b..7e3a3e5 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -27,6 +27,7 @@
     name: "VtsAidlKeyMintBenchmarkTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: [
@@ -39,7 +40,6 @@
         "libkeymint_support",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libchrome",
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index e162934..36969bb 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -40,8 +40,10 @@
     export_include_dirs: [
         "include",
     ],
+    defaults: [
+        "keymint_use_latest_hal_aidl_ndk_shared",
+    ],
     shared_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "libbase",
         "libcrypto",
         "libutils",
diff --git a/security/secureclock/aidl/vts/functional/Android.bp b/security/secureclock/aidl/vts/functional/Android.bp
index 806517d..a34668b 100644
--- a/security/secureclock/aidl/vts/functional/Android.bp
+++ b/security/secureclock/aidl/vts/functional/Android.bp
@@ -27,6 +27,7 @@
     name: "VtsAidlSecureClockTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     cflags: [
@@ -41,7 +42,6 @@
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libkeymint",
     ],
diff --git a/security/sharedsecret/aidl/vts/functional/Android.bp b/security/sharedsecret/aidl/vts/functional/Android.bp
index 94da675..1f0f6a6 100644
--- a/security/sharedsecret/aidl/vts/functional/Android.bp
+++ b/security/sharedsecret/aidl/vts/functional/Android.bp
@@ -27,6 +27,7 @@
     name: "VtsAidlSharedSecretTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: [
@@ -41,7 +42,6 @@
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk",
         "android.hardware.security.sharedsecret-V1-ndk",
         "libkeymint",
     ],
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/1.0/vts/functional/OWNERS
+++ b/sensors/1.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
index aca6961..c69f32a 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
@@ -25,7 +25,7 @@
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SensorInfo;
 
-void SensorsHidlEnvironmentV1_0::HidlTearDown() {
+void SensorsHidlEnvironmentV1_0::TearDown() {
     mStopThread = true;
     if (mPollThread.joinable()) {
         mPollThread.detach();
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index 168777d..b802e6c 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
 #define ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
 
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <android/hardware/sensors/1.0/types.h>
@@ -30,13 +30,13 @@
 
 class SensorsHidlTest;
 class SensorsHidlEnvironmentV1_0
-    : public SensorsHidlEnvironmentBase<::android::hardware::sensors::V1_0::Event> {
+    : public SensorsVtsEnvironmentBase<::android::hardware::sensors::V1_0::Event> {
   public:
-    void HidlTearDown() override;
+    void TearDown() override;
 
     using Event = ::android::hardware::sensors::V1_0::Event;
     SensorsHidlEnvironmentV1_0(const std::string& service_name)
-        : SensorsHidlEnvironmentBase(service_name) {}
+        : SensorsVtsEnvironmentBase(service_name) {}
 
   private:
     friend SensorsHidlTest;
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index d46cf5a..e4fa969 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -39,12 +39,12 @@
   public:
     virtual void SetUp() override {
         mEnvironment = new SensorsHidlEnvironmentV1_0(GetParam());
-        mEnvironment->HidlSetUp();
+        mEnvironment->SetUp();
         // Ensure that we have a valid environment before performing tests
         ASSERT_NE(S(), nullptr);
     }
 
-    virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+    virtual void TearDown() override { mEnvironment->TearDown(); }
 
   protected:
     SensorInfo defaultSensorByType(SensorType type) override;
@@ -81,7 +81,7 @@
 
     inline sp<ISensors>& S() { return mEnvironment->sensors; }
 
-    SensorsHidlEnvironmentBase<Event>* getEnvironment() override { return mEnvironment; }
+    SensorsVtsEnvironmentBase<Event>* getEnvironment() override { return mEnvironment; }
 
   private:
     // Test environment for sensors HAL.
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.0/vts/functional/OWNERS
+++ b/sensors/2.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index e212423..d7d061a 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -256,8 +256,8 @@
     // Clear the active direct connections so they are not stopped during TearDown
     auto handles = mDirectChannelHandles;
     mDirectChannelHandles.clear();
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.1/vts/functional/OWNERS
+++ b/sensors/2.1/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/common/utils/convertV2_1.h b/sensors/common/utils/convertV2_1.h
index 9231011..00359043 100644
--- a/sensors/common/utils/convertV2_1.h
+++ b/sensors/common/utils/convertV2_1.h
@@ -77,6 +77,25 @@
     return reinterpret_cast<const hidl_vec<V1_0::SensorInfo>&>(infos);
 }
 
+inline void convertToSensor(const V2_1::SensorInfo& src, sensor_t* dst) {
+    dst->name = strdup(src.name.c_str());
+    dst->vendor = strdup(src.vendor.c_str());
+    dst->version = src.version;
+    dst->handle = src.sensorHandle;
+    dst->type = (int)src.type;
+    dst->maxRange = src.maxRange;
+    dst->resolution = src.resolution;
+    dst->power = src.power;
+    dst->minDelay = src.minDelay;
+    dst->fifoReservedEventCount = src.fifoReservedEventCount;
+    dst->fifoMaxEventCount = src.fifoMaxEventCount;
+    dst->stringType = strdup(src.typeAsString.c_str());
+    dst->requiredPermission = strdup(src.requiredPermission.c_str());
+    dst->maxDelay = src.maxDelay;
+    dst->flags = src.flags;
+    dst->reserved[0] = dst->reserved[1] = 0;
+}
+
 inline void convertFromSensorEvent(const sensors_event_t& src, V2_1::Event* dst) {
     switch ((SensorType)src.type) {
         case SensorType::HINGE_ANGLE:
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
index a8c2513..d395820 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.cpp
@@ -103,7 +103,7 @@
     return succeed;
 }
 
-void SensorsHidlEnvironmentV2_X::HidlTearDown() {
+void SensorsHidlEnvironmentV2_X::TearDown() {
     mStopThread = true;
 
     if (mEventQueueFlag != nullptr) {
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
index 01f451f..5fe4d8b 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
@@ -18,7 +18,7 @@
 #define ANDROID_SENSORS_HIDL_ENVIRONMENT_V2_X_H
 
 #include "ISensorsWrapper.h"
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/2.1/ISensors.h>
 #include <android/hardware/sensors/2.1/types.h>
@@ -46,14 +46,14 @@
 };
 
 class SensorsHidlEnvironmentV2_X
-    : public SensorsHidlEnvironmentBase<::android::hardware::sensors::V2_1::Event> {
+    : public SensorsVtsEnvironmentBase<::android::hardware::sensors::V2_1::Event> {
   public:
-    virtual void HidlTearDown() override;
+    virtual void TearDown() override;
 
   protected:
     friend SensorsHidlTest;
     SensorsHidlEnvironmentV2_X(const std::string& service_name)
-        : SensorsHidlEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
+        : SensorsVtsEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
 
     /**
      * Resets the HAL with new FMQs and a new Event Flag
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index ea5dc70..7e22b19 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -170,12 +170,12 @@
   public:
     virtual void SetUp() override {
         mEnvironment = new SensorsHidlEnvironmentV2_X(GetParam());
-        mEnvironment->HidlSetUp();
+        mEnvironment->SetUp();
         // Ensure that we have a valid environment before performing tests
         ASSERT_NE(getSensors(), nullptr);
     }
 
-    virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+    virtual void TearDown() override { mEnvironment->TearDown(); }
 
   protected:
     SensorInfoType defaultSensorByType(SensorTypeVersion type) override;
@@ -216,7 +216,7 @@
 
     inline sp<ISensorsWrapperBase>& getSensors() { return mEnvironment->mSensors; }
 
-    SensorsHidlEnvironmentBase<EventType>* getEnvironment() override { return mEnvironment; }
+    SensorsVtsEnvironmentBase<EventType>* getEnvironment() override { return mEnvironment; }
 
     // Test helpers
     void runSingleFlushTest(const std::vector<SensorInfoType>& sensors, bool activateSensor,
@@ -530,32 +530,31 @@
     // Create a new environment that calls initialize()
     std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
             std::make_unique<SensorsHidlEnvironmentTest>(GetParam());
-    newEnv->HidlSetUp();
+    newEnv->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if setting up the new environment failed
     }
 
     activateAllSensors(true);
     // Verify that the old environment does not receive any events
-    EXPECT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    EXPECT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
     // Verify that the new event queue receives sensor events
-    EXPECT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, newEnv.get(), newEnv.get()).size(),
-              kNumEvents);
+    EXPECT_GE(newEnv.get()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
     activateAllSensors(false);
 
     // Cleanup the test environment
-    newEnv->HidlTearDown();
+    newEnv->TearDown();
 
     // Restore the test environment for future tests
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
 
     // Ensure that the original environment is receiving events
     activateAllSensors(true);
-    EXPECT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+    EXPECT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
     activateAllSensors(false);
 }
 
@@ -565,21 +564,21 @@
     // Verify that events are received
     constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
     constexpr int32_t kNumEvents = 1;
-    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
 
     // Clear the active sensor handles so they are not disabled during TearDown
     auto handles = mSensorHandles;
     mSensorHandles.clear();
-    getEnvironment()->HidlTearDown();
-    getEnvironment()->HidlSetUp();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
     if (HasFatalFailure()) {
         return;  // Exit early if resetting the environment failed
     }
 
     // Verify no events are received until sensors are re-activated
-    ASSERT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    ASSERT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
     activateAllSensors(true);
-    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
 
     // Disable sensors
     activateAllSensors(false);
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
deleted file mode 100644
index 19dfbe5..0000000
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 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_SENSORS_HIDL_ENVIRONMENT_BASE_H
-#define ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
-
-#include <gtest/gtest.h>
-
-#include <atomic>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-template <class Event>
-class IEventCallback {
-  public:
-    virtual ~IEventCallback() = default;
-    virtual void onEvent(const Event& event) = 0;
-};
-
-template <class Event>
-class SensorsHidlEnvironmentBase {
-  public:
-    virtual void HidlSetUp() {
-        ASSERT_TRUE(resetHal()) << "could not get hidl service";
-
-        mCollectionEnabled = false;
-        startPollingThread();
-
-        // In case framework just stopped for test and there is sensor events in the pipe,
-        // wait some time for those events to be cleared to avoid them messing up the test.
-        std::this_thread::sleep_for(std::chrono::seconds(3));
-    }
-
-    virtual void HidlTearDown() = 0;
-
-    // Get and clear all events collected so far (like "cat" shell command).
-    // If output is nullptr, it clears all collected events.
-    void catEvents(std::vector<Event>* output) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        if (output) {
-            output->insert(output->end(), mEvents.begin(), mEvents.end());
-        }
-        mEvents.clear();
-    }
-
-    // set sensor event collection status
-    void setCollection(bool enable) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCollectionEnabled = enable;
-    }
-
-    void registerCallback(IEventCallback<Event>* callback) {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCallback = callback;
-    }
-
-    void unregisterCallback() {
-        std::lock_guard<std::mutex> lock(mEventsMutex);
-        mCallback = nullptr;
-    }
-
-   protected:
-     SensorsHidlEnvironmentBase(const std::string& service_name)
-         : mCollectionEnabled(false), mCallback(nullptr) {
-         mServiceName = service_name;
-     }
-     virtual ~SensorsHidlEnvironmentBase(){};
-
-     void addEvent(const Event& ev) {
-         std::lock_guard<std::mutex> lock(mEventsMutex);
-         if (mCollectionEnabled) {
-             mEvents.push_back(ev);
-         }
-
-         if (mCallback != nullptr) {
-             mCallback->onEvent(ev);
-         }
-     }
-
-     virtual void startPollingThread() = 0;
-     virtual bool resetHal() = 0;
-
-     std::string mServiceName;
-     bool mCollectionEnabled;
-     std::atomic_bool mStopThread;
-     std::thread mPollThread;
-     std::vector<Event> mEvents;
-     std::mutex mEventsMutex;
-
-     IEventCallback<Event>* mCallback;
-
-     GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase<Event>);
-};
-
-#endif  // ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index af14009..f3cbd78 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -18,8 +18,8 @@
 #define ANDROID_SENSORS_HIDL_TEST_BASE_H
 
 #include "sensors-vts-utils/SensorEventsChecker.h"
-#include "sensors-vts-utils/SensorsHidlEnvironmentBase.h"
 #include "sensors-vts-utils/SensorsTestSharedMemory.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <android/hardware/sensors/1.0/types.h>
@@ -163,7 +163,7 @@
         : mAccelNormChecker(Vec3NormChecker<EventType>::byNominal(GRAVITY_EARTH, 1.0f /*m/s^2*/)),
           mGyroNormChecker(Vec3NormChecker<EventType>::byNominal(0.f, 0.1f /*rad/s*/)) {}
 
-    virtual SensorsHidlEnvironmentBase<EventType>* getEnvironment() = 0;
+    virtual SensorsVtsEnvironmentBase<EventType>* getEnvironment() = 0;
 
     virtual void SetUp() override {}
 
@@ -198,49 +198,6 @@
                                             RateLevel rate,
                                             ISensors::configDirectReport_cb _hidl_cb) = 0;
 
-    std::vector<EventType> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
-                                         bool clearBeforeStart = true,
-                                         bool changeCollection = true) {
-        return collectEvents(timeLimitUs, nEventLimit, getEnvironment(), clearBeforeStart,
-                             changeCollection);
-    }
-
-    std::vector<EventType> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
-                                         SensorsHidlEnvironmentBase<EventType>* environment,
-                                         bool clearBeforeStart = true,
-                                         bool changeCollection = true) {
-        std::vector<EventType> events;
-        constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
-
-        ALOGI("collect max of %zu events for %d us, clearBeforeStart %d", nEventLimit, timeLimitUs,
-              clearBeforeStart);
-
-        if (changeCollection) {
-            environment->setCollection(true);
-        }
-        if (clearBeforeStart) {
-            environment->catEvents(nullptr);
-        }
-
-        while (timeLimitUs > 0) {
-            useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
-            usleep(duration);
-            timeLimitUs -= duration;
-
-            environment->catEvents(&events);
-            if (events.size() >= nEventLimit) {
-                break;
-            }
-            ALOGV("time to go = %d, events to go = %d", (int)timeLimitUs,
-                  (int)(nEventLimit - events.size()));
-        }
-
-        if (changeCollection) {
-            environment->setCollection(false);
-        }
-        return events;
-    }
-
     void testStreamingOperation(SensorTypeVersion type, std::chrono::nanoseconds samplingPeriod,
                                 std::chrono::seconds duration,
                                 const SensorEventsChecker<EventType>& checker) {
@@ -268,7 +225,7 @@
 
         ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
         ASSERT_EQ(activate(handle, 1), Result::OK);
-        events = collectEvents(minTimeUs, minNEvent, getEnvironment(), true /*clearBeforeStart*/);
+        events = getEnvironment()->collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
         ASSERT_EQ(activate(handle, 0), Result::OK);
 
         ALOGI("Collected %zu samples", events.size());
@@ -335,13 +292,13 @@
         ASSERT_EQ(activate(handle, 1), Result::OK);
 
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
-        events1 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
+        events1 = getEnvironment()->collectEvents(collectionTimeoutUs, minNEvent);
 
         // second collection, without stopping the sensor
         ASSERT_EQ(batch(handle, secondCollectionPeriod, batchingPeriodInNs), Result::OK);
 
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
-        events2 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
+        events2 = getEnvironment()->collectEvents(collectionTimeoutUs, minNEvent);
 
         // end of collection, stop sensor
         ASSERT_EQ(activate(handle, 0), Result::OK);
@@ -447,16 +404,17 @@
 
         getEnvironment()->setCollection(true);
         // clean existing collections
-        collectEvents(0 /*timeLimitUs*/, 0 /*nEventLimit*/, true /*clearBeforeStart*/,
-                      false /*change collection*/);
+        getEnvironment()->collectEvents(0 /*timeLimitUs*/, 0 /*nEventLimit*/,
+                                        true /*clearBeforeStart*/, false /*change collection*/);
 
         // 0.8 + 0.2 times the batching period
         usleep(batchingPeriodInNs / 1000 * 2 / 10);
         ASSERT_EQ(flush(handle), Result::OK);
 
         // plus some time for the event to deliver
-        events = collectEvents(allowedBatchDeliverTimeNs / 1000, minFifoCount,
-                               false /*clearBeforeStart*/, false /*change collection*/);
+        events = getEnvironment()->collectEvents(allowedBatchDeliverTimeNs / 1000, minFifoCount,
+                                                 false /*clearBeforeStart*/,
+                                                 false /*change collection*/);
 
         getEnvironment()->setCollection(false);
         ASSERT_EQ(activate(handle, 0), Result::OK);
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
new file mode 100644
index 0000000..17a96ed
--- /dev/null
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2018 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_SENSORS_VTS_ENVIRONMENT_BASE_H
+#define ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
+
+#include <gtest/gtest.h>
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <log/log.h>
+
+template <class Event>
+class IEventCallback {
+  public:
+    virtual ~IEventCallback() = default;
+    virtual void onEvent(const Event& event) = 0;
+};
+
+template <class Event>
+class SensorsVtsEnvironmentBase {
+  public:
+    virtual void SetUp() {
+        ASSERT_TRUE(resetHal()) << "could not get hidl service";
+
+        mCollectionEnabled = false;
+        startPollingThread();
+
+        // In case framework just stopped for test and there is sensor events in the pipe,
+        // wait some time for those events to be cleared to avoid them messing up the test.
+        std::this_thread::sleep_for(std::chrono::seconds(3));
+    }
+
+    virtual void TearDown() = 0;
+
+    // Get and clear all events collected so far (like "cat" shell command).
+    // If output is nullptr, it clears all collected events.
+    void catEvents(std::vector<Event>* output) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        if (output) {
+            output->insert(output->end(), mEvents.begin(), mEvents.end());
+        }
+        mEvents.clear();
+    }
+
+    // set sensor event collection status
+    void setCollection(bool enable) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCollectionEnabled = enable;
+    }
+
+    void registerCallback(IEventCallback<Event>* callback) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCallback = callback;
+    }
+
+    void unregisterCallback() {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        mCallback = nullptr;
+    }
+
+    std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
+                                     bool clearBeforeStart = true, bool changeCollection = true) {
+        std::vector<Event> events;
+        constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
+
+        ALOGI("collect max of %zu events for %d us, clearBeforeStart %d", nEventLimit, timeLimitUs,
+              clearBeforeStart);
+
+        if (changeCollection) {
+            setCollection(true);
+        }
+        if (clearBeforeStart) {
+            catEvents(nullptr);
+        }
+
+        while (timeLimitUs > 0) {
+            useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
+            usleep(duration);
+            timeLimitUs -= duration;
+
+            catEvents(&events);
+            if (events.size() >= nEventLimit) {
+                break;
+            }
+            ALOGV("time to go = %d, events to go = %d", (int)timeLimitUs,
+                  (int)(nEventLimit - events.size()));
+        }
+
+        if (changeCollection) {
+            setCollection(false);
+        }
+        return events;
+    }
+
+  protected:
+    SensorsVtsEnvironmentBase(const std::string& service_name)
+        : mCollectionEnabled(false), mCallback(nullptr) {
+        mServiceName = service_name;
+    }
+    virtual ~SensorsVtsEnvironmentBase(){};
+
+    void addEvent(const Event& ev) {
+        std::lock_guard<std::mutex> lock(mEventsMutex);
+        if (mCollectionEnabled) {
+            mEvents.push_back(ev);
+        }
+
+        if (mCallback != nullptr) {
+            mCallback->onEvent(ev);
+        }
+    }
+
+    virtual void startPollingThread() = 0;
+    virtual bool resetHal() = 0;
+
+    std::string mServiceName;
+    bool mCollectionEnabled;
+    std::atomic_bool mStopThread;
+    std::thread mPollThread;
+    std::vector<Event> mEvents;
+    std::mutex mEventsMutex;
+
+    IEventCallback<Event>* mCallback;
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsVtsEnvironmentBase<Event>);
+};
+
+#endif  // ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
index 5d5b943..2b1b379 100644
--- a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     task_profiles ProcessCapacityHigh
+    onrestart restart media.tuner
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
index ba66595..4a642a0 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -128,7 +128,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
index 3718a93..62ee520 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
@@ -3,4 +3,5 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index bc57821..a595a93 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -180,7 +180,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
index 8e31bd9..95ecc51 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
@@ -47,4 +47,5 @@
   INVALID_FRONTEND_ID = -1,
   INVALID_LNB_ID = -1,
   INVALID_KEYTOKEN = 0,
+  INVALID_TABINFO_VERSION = -1,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 95911f9..3e5df2d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -36,4 +36,5 @@
 @VintfStability
 parcelable DemuxFilterAvSettings {
   boolean isPassthrough;
+  boolean isSecureMemory;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 17bdd1f..02c478f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -36,6 +36,6 @@
 @VintfStability
 parcelable DemuxFilterRecordSettings {
   int tsIndexMask;
-  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.NONE;
   android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 3fd1910..371e075 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -36,5 +36,6 @@
 @VintfStability
 union DemuxFilterScIndexMask {
   int scIndex;
+  int scAvc;
   int scHevc;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 91a5e52..30ec29a 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -38,5 +38,5 @@
   NONE = 0,
   SC = 1,
   SC_HEVC = 2,
-  UNDEFINED = 3,
+  SC_AVC = 3,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
index 6eadbb7..651b66c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,14 @@
 // 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;
+package android.hardware.tv.tuner;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum DemuxScAvcIndex {
+  UNDEFINED = 0,
+  I_SLICE = 1,
+  P_SLICE = 2,
+  B_SLICE = 4,
+  SI_SLICE = 8,
+  SP_SLICE = 16,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index 3035dad..670b34e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -35,6 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxScHevcIndex {
+  UNDEFINED = 0,
   SPS = 1,
   AUD = 2,
   SLICE_CE_BLA_W_LP = 4,
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
index 808b212..25f0585 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -40,9 +40,4 @@
   P_FRAME = 2,
   B_FRAME = 4,
   SEQUENCE = 8,
-  I_SLICE = 16,
-  P_SLICE = 32,
-  B_SLICE = 64,
-  SI_SLICE = 128,
-  SP_SLICE = 256,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 5e03731..ac38731 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -38,4 +38,5 @@
   android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode atsc3 = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
   android.hardware.tv.tuner.FrontendCableTimeInterleaveMode dvbc;
   android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode dtmb;
+  android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode isdbt;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 097fcb8..dbf631b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -40,4 +40,7 @@
   int modulationCap;
   int coderateCap;
   int guardIntervalCap;
+  int timeInterleaveCap;
+  boolean isSegmentAuto;
+  boolean isFullSegment;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
similarity index 74%
copy from radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
index d7eecbb..0055793 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@
 // 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.voice;
+package android.hardware.tv.tuner;
+/* @hide */
 @VintfStability
-parcelable CdmaInformationRecords {
-  android.hardware.radio.voice.CdmaInformationRecord[] infoRec;
+parcelable FrontendIsdbtLayerSettings {
+  android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode timeInterleave = android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+  int numOfSegment;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
similarity index 88%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
index 6eadbb7..133887f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,12 @@
 // 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;
+package android.hardware.tv.tuner;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum FrontendIsdbtPartialReceptionFlag {
+  UNDEFINED = 0,
+  AUTO = 1,
+  FALSE = 2,
+  TRUE = 4,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 6249097..605bc21 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -38,10 +38,10 @@
   long frequency;
   long endFrequency;
   android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
-  android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendIsdbtBandwidth.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtMode mode = android.hardware.tv.tuner.FrontendIsdbtMode.UNDEFINED;
-  android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
   android.hardware.tv.tuner.FrontendIsdbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendIsdbtGuardInterval.UNDEFINED;
   int serviceAreaId;
+  android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag = android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtLayerSettings[] layerSettings;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
similarity index 78%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
index 0c6c513..50adde9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,15 +31,22 @@
 // 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;
+package android.hardware.tv.tuner;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum SapResultCode {
-  SUCCESS = 0,
-  GENERIC_FAILURE = 1,
-  CARD_NOT_ACCESSSIBLE = 2,
-  CARD_ALREADY_POWERED_OFF = 3,
-  CARD_REMOVED = 4,
-  CARD_ALREADY_POWERED_ON = 5,
-  DATA_NOT_AVAILABLE = 6,
-  NOT_SUPPORTED = 7,
+enum FrontendIsdbtTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  INTERLEAVE_1_0 = 2,
+  INTERLEAVE_1_4 = 4,
+  INTERLEAVE_1_8 = 8,
+  INTERLEAVE_1_16 = 16,
+  INTERLEAVE_2_0 = 32,
+  INTERLEAVE_2_2 = 64,
+  INTERLEAVE_2_4 = 128,
+  INTERLEAVE_2_8 = 256,
+  INTERLEAVE_3_0 = 512,
+  INTERLEAVE_3_1 = 1024,
+  INTERLEAVE_3_2 = 2048,
+  INTERLEAVE_3_4 = 4096,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index 6296cfc..7677221 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -72,4 +72,6 @@
   boolean isMiso;
   boolean isLinear;
   boolean isShortFrames;
+  android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
+  android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index 7b8bc47..6342479 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -72,4 +72,6 @@
   IS_MISO = 34,
   IS_LINEAR = 35,
   IS_SHORT_FRAMES = 36,
+  ISDBT_MODE = 37,
+  ISDBT_PARTIAL_RECEPTION_FLAG = 38,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
index 891794a..0751d26 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
@@ -83,4 +83,9 @@
      * An invalid key token. It is used to remove the current key from the descrambler.
      */
     INVALID_KEYTOKEN = 0x00,
+
+     /**
+     * An invalid section filter version number.
+     */
+    INVALID_TABINFO_VERSION = 0xFFFFFFFF,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 30a1054..fe4db5b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -26,4 +26,9 @@
      * true if the filter output goes to decoder directly in pass through mode.
      */
     boolean isPassthrough;
+
+    /**
+     * true if the avMemory should be allocated from secure area.
+     */
+    boolean isSecureMemory;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 2f88864..475910b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -30,7 +30,7 @@
      */
     int tsIndexMask;
 
-    DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.UNDEFINED;
+    DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.NONE;
 
     DemuxFilterScIndexMask scIndexMask;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index a9f4b6f..4036b06 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.tv.tuner;
 
+import android.hardware.tv.tuner.DemuxScAvcIndex;
 import android.hardware.tv.tuner.DemuxScHevcIndex;
 import android.hardware.tv.tuner.DemuxScIndex;
 
@@ -30,6 +31,11 @@
     int scIndex;
 
     /**
+     * Indexes defined by DemuxScAvcIndex.
+     */
+    int scAvc;
+
+    /**
      * Indexes defined by DemuxScHevcIndex.
      */
     int scHevc;
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
index 898b9cc..dbd438c 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -28,7 +28,8 @@
     int tableId;
 
     /**
-     * Version number for Section Filter
+     * Optional version number for Section Filter. It should be ignored if INVALID_TABINFO_VERSION
+     * is set.
      */
     int version;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 44b985c..98427f7 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -39,7 +39,7 @@
     SC_HEVC,
 
     /**
-     * SC index is undefined
+     * Use Start Code index for AVC
      */
-    UNDEFINED,
+    SC_AVC,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..ed418f2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 14496-10.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScAvcIndex {
+    UNDEFINED = 0,
+
+    /**
+     * All blocks are coded as I blocks.
+     */
+    I_SLICE = 1 << 0,
+
+    /**
+     * Blocks are coded as I or P blocks.
+     */
+    P_SLICE = 1 << 1,
+
+    /**
+     * Blocks are coded as I, P or B blocks.
+     */
+    B_SLICE = 1 << 2,
+
+    /**
+     * A so-called switching I slice that is coded.
+     */
+    SI_SLICE = 1 << 3,
+
+    /**
+     * A so-called switching P slice that is coded.
+     */
+    SP_SLICE = 1 << 4,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index f2ddd00..0d1f112 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -23,6 +23,8 @@
 @VintfStability
 @Backing(type="int")
 enum DemuxScHevcIndex {
+    UNDEFINED = 0,
+
     SPS = 1 << 0,
 
     AUD = 1 << 1,
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
index 0aef739..4fed1e5 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -18,7 +18,7 @@
 
 /**
  * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
- * according to ISO/IEC 13818-1 and Slice Groups according to ISO/IEC 14496-10.
+ * according to ISO/IEC 13818-1.
  * @hide
  */
 @VintfStability
@@ -45,29 +45,4 @@
      * Start Code is for a new Sequence
      */
     SEQUENCE = 1 << 3,
-
-    /**
-     * All blocks are coded as I blocks.
-     */
-    I_SLICE = 1 << 4,
-
-    /**
-     * Blocks are coded as I or P blocks.
-     */
-    P_SLICE = 1 << 5,
-
-    /**
-     * Blocks are coded as I, P or B blocks.
-     */
-    B_SLICE = 1 << 6,
-
-    /**
-     * A so-called switching I slice that is coded.
-     */
-    SI_SLICE = 1 << 7,
-
-    /**
-     * A so-called switching P slice that is coded.
-     */
-    SP_SLICE = 1 << 8,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
index 8174a51..3f1ca35 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
@@ -22,6 +22,7 @@
  * Filter Delay Hint
  * Gives information to the filter to assist in delaying / accumulating filter events.
  * See FilterDelayHintType for more information regarding the hintValue units.
+ * Note: this hint is not valid for media filters.
  * @hide
  */
 @VintfStability
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 3aa17dd..106ef67 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -19,6 +19,7 @@
 import android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode;
 import android.hardware.tv.tuner.FrontendCableTimeInterleaveMode;
 import android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
 
 /**
  * @hide
@@ -31,4 +32,6 @@
     FrontendCableTimeInterleaveMode dvbc;
 
     FrontendDtmbTimeInterleaveMode dtmb;
+
+    FrontendIsdbtTimeInterleaveMode isdbt;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 4b764ad..b2bdfd4 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -46,4 +46,19 @@
      * Guard Interval Types defined by FrontendIsdbtGuardInterval.
      */
     int guardIntervalCap;
+
+    /**
+     * Time Interleaves defined by FrontendIsdbtTimeInterleaveMode.
+     */
+    int timeInterleaveCap;
+
+    /**
+     * If segment auto Supported or not.
+     */
+    boolean isSegmentAuto;
+
+    /**
+     * If full segment supported or not.
+     */
+    boolean isFullSegment;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
new file mode 100644
index 0000000..0b44ecb
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendIsdbtCoderate;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
+
+/**
+ * Layer Settings for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbtLayerSettings {
+    FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
+
+    FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
+
+    FrontendIsdbtTimeInterleaveMode timeInterleave = FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+
+    /**
+     * 0 ~ 13 and 0xFF(Auto)
+     */
+    int numOfSegment;
+}
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
similarity index 61%
copy from radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
copy to tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
index 46a9b1a..81c28cd 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,23 @@
  * limitations under the License.
  */
 
-package android.hardware.radio.voice;
+package android.hardware.tv.tuner;
 
-import android.hardware.radio.voice.CdmaInformationRecord;
-
+/**
+ * Partial Reception Flag for an ISTB-T Frontend.
+ * @hide
+ */
 @VintfStability
-parcelable CdmaInformationRecords {
+@Backing(type="int")
+enum FrontendIsdbtPartialReceptionFlag {
+    UNDEFINED = 0,
+
     /**
-     * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
+     * Hardware is able to detect and set Partial Reception Flag automatically.
      */
-    CdmaInformationRecord[] infoRec;
+    AUTO = 1 << 0,
+
+    FALSE = 1 << 1,
+
+    TRUE = 1 << 2,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 08f6130..23a4769 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -17,10 +17,10 @@
 package android.hardware.tv.tuner;
 
 import android.hardware.tv.tuner.FrontendIsdbtBandwidth;
-import android.hardware.tv.tuner.FrontendIsdbtCoderate;
 import android.hardware.tv.tuner.FrontendIsdbtGuardInterval;
+import android.hardware.tv.tuner.FrontendIsdbtLayerSettings;
 import android.hardware.tv.tuner.FrontendIsdbtMode;
-import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
 import android.hardware.tv.tuner.FrontendSpectralInversion;
 
 /**
@@ -41,15 +41,15 @@
 
     FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
 
-    FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
-
     FrontendIsdbtBandwidth bandwidth = FrontendIsdbtBandwidth.UNDEFINED;
 
     FrontendIsdbtMode mode = FrontendIsdbtMode.UNDEFINED;
 
-    FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
-
     FrontendIsdbtGuardInterval guardInterval = FrontendIsdbtGuardInterval.UNDEFINED;
 
     int serviceAreaId;
+
+    FrontendIsdbtPartialReceptionFlag partialReceptionFlag = FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+
+    FrontendIsdbtLayerSettings[] layerSettings;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
new file mode 100644
index 0000000..6192fca
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Time Interleave Mode for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtTimeInterleaveMode {
+    UNDEFINED = 0,
+
+    /**
+     * Hardware is able to detect and set Time Interleave Mode automatically.
+     */
+    AUTO = 1 << 0,
+
+    INTERLEAVE_1_0 = 1 << 1,
+
+    INTERLEAVE_1_4 = 1 << 2,
+
+    INTERLEAVE_1_8 = 1 << 3,
+
+    INTERLEAVE_1_16 = 1 << 4,
+
+    INTERLEAVE_2_0 = 1 << 5,
+
+    INTERLEAVE_2_2 = 1 << 6,
+
+    INTERLEAVE_2_4 = 1 << 7,
+
+    INTERLEAVE_2_8 = 1 << 8,
+
+    INTERLEAVE_3_0 = 1 << 9,
+
+    INTERLEAVE_3_1 = 1 << 10,
+
+    INTERLEAVE_3_2 = 1 << 11,
+
+    INTERLEAVE_3_4 = 1 << 12,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index ddbd0f8..9302b76 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -21,6 +21,8 @@
 import android.hardware.tv.tuner.FrontendGuardInterval;
 import android.hardware.tv.tuner.FrontendInnerFec;
 import android.hardware.tv.tuner.FrontendInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtMode;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
 import android.hardware.tv.tuner.FrontendModulation;
 import android.hardware.tv.tuner.FrontendModulationStatus;
 import android.hardware.tv.tuner.FrontendRollOff;
@@ -190,4 +192,14 @@
      * If short frames is enabled or not.
      */
     boolean isShortFrames;
+
+    /**
+     * ISDB-T Mode.
+     */
+    FrontendIsdbtMode isdbtMode;
+
+    /**
+     * ISDB-T Partial Reception Flag.
+     */
+    FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 93b75b0..103a4ab 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -208,4 +208,14 @@
      * If short frames is enabled or not.
      */
     IS_SHORT_FRAMES,
+
+    /**
+     * ISDB-T Mode.
+     */
+    ISDBT_MODE,
+
+    /**
+     * ISDB-T Partial Reception Flag.
+     */
+    ISDBT_PARTIAL_RECEPTION_FLAG,
 }
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 345a984..54037be 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -35,7 +35,11 @@
 #define WAIT_TIMEOUT 3000000000
 
 FilterCallbackScheduler::FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb)
-    : mCallback(cb), mDataLength(0), mTimeDelayInMs(0), mDataSizeDelayInBytes(0) {
+    : mCallback(cb),
+      mIsConditionMet(false),
+      mDataLength(0),
+      mTimeDelayInMs(0),
+      mDataSizeDelayInBytes(0) {
     start();
 }
 
@@ -44,12 +48,14 @@
 }
 
 void FilterCallbackScheduler::onFilterEvent(DemuxFilterEvent&& event) {
-    std::lock_guard<std::mutex> lock(mLock);
+    std::unique_lock<std::mutex> lock(mLock);
     mCallbackBuffer.push_back(std::move(event));
     mDataLength += getDemuxFilterEventDataLength(event);
 
-    if (mDataLength >= mDataSizeDelayInBytes) {
-        // size limit has been reached, send out events
+    if (isDataSizeDelayConditionMetLocked()) {
+        mIsConditionMet = true;
+        // unlock, so thread is not immediately blocked when it is notified.
+        lock.unlock();
         mCv.notify_all();
     }
 }
@@ -60,22 +66,29 @@
     }
 }
 
+void FilterCallbackScheduler::flushEvents() {
+    std::unique_lock<std::mutex> lock(mLock);
+    mCallbackBuffer.clear();
+    mDataLength = 0;
+}
+
 void FilterCallbackScheduler::setTimeDelayHint(int timeDelay) {
-    // updating the setTimeDelay does not go into effect until the condition
-    // variable times out or is notified.
-    // One possibility is to notify the condition variable right away when the
-    // time delay changes, but I don't see the benefit over waiting for the next
-    // timeout / push, since -- in any case -- this will not change very often.
+    std::unique_lock<std::mutex> lock(mLock);
     mTimeDelayInMs = timeDelay;
+    // always notify condition variable to update timeout
+    mIsConditionMet = true;
+    lock.unlock();
+    mCv.notify_all();
 }
 
 void FilterCallbackScheduler::setDataSizeDelayHint(int dataSizeDelay) {
-    // similar to updating the time delay hint, when mDataSizeDelayInBytes
-    // changes, this will not go into immediate effect, but will wait until the
-    // next filterEvent.
-    // We could technically check the current data length and notify the
-    // condition variable if we wanted to, but again, this may be overkill.
+    std::unique_lock<std::mutex> lock(mLock);
     mDataSizeDelayInBytes = dataSizeDelay;
+    if (isDataSizeDelayConditionMetLocked()) {
+        mIsConditionMet = true;
+        lock.unlock();
+        mCv.notify_all();
+    }
 }
 
 bool FilterCallbackScheduler::hasCallbackRegistered() const {
@@ -90,6 +103,11 @@
 void FilterCallbackScheduler::stop() {
     mIsRunning = false;
     if (mCallbackThread.joinable()) {
+        {
+            std::lock_guard<std::mutex> lock(mLock);
+            mIsConditionMet = true;
+        }
+        mCv.notify_all();
         mCallbackThread.join();
     }
 }
@@ -102,27 +120,42 @@
 
 void FilterCallbackScheduler::threadLoopOnce() {
     std::unique_lock<std::mutex> lock(mLock);
-    // mTimeDelayInMs is an atomic value, so it should be copied into a local
-    // variable before use (to make sure both the if statement and wait_for use
-    // the same value).
-    int timeDelayInMs = mTimeDelayInMs;
-    if (timeDelayInMs > 0) {
-        mCv.wait_for(lock, std::chrono::milliseconds(timeDelayInMs));
+    if (mTimeDelayInMs > 0) {
+        // Note: predicate protects from lost and spurious wakeups
+        mCv.wait_for(lock, std::chrono::milliseconds(mTimeDelayInMs),
+                     [this] { return mIsConditionMet; });
     } else {
-        // no reason to timeout, just wait until main thread determines it's
-        // okay to send data.
-        mCv.wait(lock);
+        // Note: predicate protects from lost and spurious wakeups
+        mCv.wait(lock, [this] { return mIsConditionMet; });
     }
+    mIsConditionMet = false;
 
     // condition_variable wait locks mutex on timeout / notify
-    if (!mCallbackBuffer.empty()) {
+    // Note: if stop() has been called in the meantime, do not send more filter
+    // events.
+    if (mIsRunning && !mCallbackBuffer.empty()) {
         if (mCallback) {
             mCallback->onFilterEvent(mCallbackBuffer);
         }
         mCallbackBuffer.clear();
         mDataLength = 0;
     }
-    lock.unlock();
+}
+
+// mLock needs to be held to call this function
+bool FilterCallbackScheduler::isDataSizeDelayConditionMetLocked() {
+    if (mDataSizeDelayInBytes == 0) {
+        // Data size delay is disabled.
+        if (mTimeDelayInMs == 0) {
+            // Events should only be sent immediately if time delay is disabled
+            // as well.
+            return true;
+        }
+        return false;
+    }
+
+    // Data size delay is enabled.
+    return mDataLength >= mDataSizeDelayInBytes;
 }
 
 int FilterCallbackScheduler::getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
@@ -332,6 +365,8 @@
         mFilterThread.join();
     }
 
+    mCallbackScheduler.flushEvents();
+
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -531,7 +566,9 @@
     // For the first time of filter output, implementation needs to send the filter
     // Event Callback without waiting for the DATA_CONSUMED to init the process.
     while (mFilterThreadRunning) {
+        std::unique_lock<std::mutex> lock(mFilterEventsLock);
         if (mFilterEvents.size() == 0) {
+            lock.unlock();
             if (DEBUG_FILTER) {
                 ALOGD("[Filter] wait for filter data output.");
             }
@@ -548,6 +585,7 @@
                 mConfigured = false;
             }
 
+            // lock is still being held
             for (auto&& event : mFilterEvents) {
                 mCallbackScheduler.onFilterEvent(std::move(event));
             }
@@ -730,7 +768,6 @@
 }
 
 ::ndk::ScopedAStatus Filter::startPesFilterHandler() {
-    std::lock_guard<std::mutex> lock(mFilterEventsLock);
     if (mFilterOutput.empty()) {
         return ::ndk::ScopedAStatus::ok();
     }
@@ -785,7 +822,11 @@
             ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
         }
 
-        mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
+        {
+            std::lock_guard<std::mutex> lock(mFilterEventsLock);
+            mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
+        }
+
         mPesOutput.clear();
     }
 
@@ -800,7 +841,6 @@
 }
 
 ::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
-    std::lock_guard<std::mutex> lock(mFilterEventsLock);
     if (mFilterOutput.empty()) {
         return ::ndk::ScopedAStatus::ok();
     }
@@ -889,7 +929,12 @@
             .firstMbInSlice = 0,  // random address
     };
 
-    mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
+    {
+        std::lock_guard<std::mutex> lock(mFilterEventsLock);
+        mFilterEvents.push_back(
+                DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
+    }
+
     mRecordFilterOutput.clear();
     return ::ndk::ScopedAStatus::ok();
 }
@@ -907,7 +952,6 @@
 bool Filter::writeSectionsAndCreateEvent(vector<int8_t>& data) {
     // TODO check how many sections has been read
     ALOGD("[Filter] section handler");
-    std::lock_guard<std::mutex> lock(mFilterEventsLock);
     if (!writeDataToFilterMQ(data)) {
         return false;
     }
@@ -919,7 +963,12 @@
             .sectionNum = 1,
             .dataLength = static_cast<int32_t>(data.size()),
     };
-    mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+
+    {
+        std::lock_guard<std::mutex> lock(mFilterEventsLock);
+        mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+    }
+
     return true;
 }
 
@@ -1017,7 +1066,11 @@
         mediaEvent.pts = mPts;
         mPts = 0;
     }
-    mFilterEvents.push_back(std::move(event));
+
+    {
+        std::lock_guard<std::mutex> lock(mFilterEventsLock);
+        mFilterEvents.push_back(std::move(event));
+    }
 
     // Clear and log
     native_handle_close(nativeHandle);
@@ -1057,7 +1110,11 @@
         mediaEvent.pts = mPts;
         mPts = 0;
     }
-    mFilterEvents.push_back(std::move(event));
+
+    {
+        std::lock_guard<std::mutex> lock(mFilterEventsLock);
+        mFilterEvents.push_back(std::move(event));
+    }
 
     mSharedAvMemOffset += output.size();
 
@@ -1081,8 +1138,6 @@
 
 void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
     AudioExtraMetaData audio;
-    events.resize(1);
-
     audio.adFade = 1;
     audio.adPan = 2;
     audio.versionTextTag = 3;
@@ -1090,17 +1145,15 @@
     audio.adGainFront = 5;
     audio.adGainSurround = 6;
 
-    events[0] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
-    events[0].get<DemuxFilterEvent::Tag::media>().streamId = 1;
-    events[0].get<DemuxFilterEvent::Tag::media>().isPtsPresent = true;
-    events[0].get<DemuxFilterEvent::Tag::media>().dataLength = 3;
-    events[0].get<DemuxFilterEvent::Tag::media>().offset = 4;
-    events[0].get<DemuxFilterEvent::Tag::media>().isSecureMemory = true;
-    events[0].get<DemuxFilterEvent::Tag::media>().mpuSequenceNumber = 6;
-    events[0].get<DemuxFilterEvent::Tag::media>().isPesPrivateData = true;
-    events[0]
-            .get<DemuxFilterEvent::Tag::media>()
-            .extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
+    DemuxFilterMediaEvent mediaEvent;
+    mediaEvent.streamId = 1;
+    mediaEvent.isPtsPresent = true;
+    mediaEvent.dataLength = 3;
+    mediaEvent.offset = 4;
+    mediaEvent.isSecureMemory = true;
+    mediaEvent.mpuSequenceNumber = 6;
+    mediaEvent.isPesPrivateData = true;
+    mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
 
     int av_fd = createAvIonFd(BUFFER_SIZE_16M);
     if (av_fd == -1) {
@@ -1118,16 +1171,16 @@
     uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
     mDataId2Avfd[dataId] = dup(av_fd);
 
-    events[0].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
-    events[0].get<DemuxFilterEvent::Tag::media>().avMemory = ::android::dupToAidl(nativeHandle);
+    mediaEvent.avDataId = static_cast<int64_t>(dataId);
+    mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>(std::move(mediaEvent)));
 
     native_handle_close(nativeHandle);
     native_handle_delete(nativeHandle);
 }
 
 void Filter::createTsRecordEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(2);
-
     DemuxPid pid;
     DemuxFilterScIndexMask mask;
     DemuxFilterTsRecordEvent tsRecord1;
@@ -1142,13 +1195,11 @@
     tsRecord2.pts = 1;
     tsRecord2.firstMbInSlice = 2;  // random address
 
-    events[0].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord1);
-    events[1].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord2);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(std::move(tsRecord1)));
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(std::move(tsRecord2)));
 }
 
 void Filter::createMmtpRecordEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(2);
-
     DemuxFilterMmtpRecordEvent mmtpRecord1;
     mmtpRecord1.scHevcIndexMask = 1;
     mmtpRecord1.byteNumber = 2;
@@ -1159,36 +1210,32 @@
     mmtpRecord2.firstMbInSlice = 3;
     mmtpRecord2.tsIndexMask = 4;
 
-    events[0].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord1);
-    events[1].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord2);
+    events.push_back(
+            DemuxFilterEvent::make<DemuxFilterEvent::Tag::mmtpRecord>(std::move(mmtpRecord1)));
+    events.push_back(
+            DemuxFilterEvent::make<DemuxFilterEvent::Tag::mmtpRecord>(std::move(mmtpRecord2)));
 }
 
 void Filter::createSectionEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterSectionEvent section;
     section.tableId = 1;
     section.version = 2;
     section.sectionNum = 3;
     section.dataLength = 0;
 
-    events[0].set<DemuxFilterEvent::Tag::section>(section);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(std::move(section)));
 }
 
 void Filter::createPesEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterPesEvent pes;
     pes.streamId = 1;
     pes.dataLength = 1;
     pes.mpuSequenceNumber = 2;
 
-    events[0].set<DemuxFilterEvent::Tag::pes>(pes);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(std::move(pes)));
 }
 
 void Filter::createDownloadEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterDownloadEvent download;
     download.itemId = 1;
     download.mpuSequenceNumber = 2;
@@ -1196,41 +1243,36 @@
     download.lastItemFragmentIndex = 4;
     download.dataLength = 0;
 
-    events[0].set<DemuxFilterEvent::Tag::download>(download);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::download>(std::move(download)));
 }
 
 void Filter::createIpPayloadEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterIpPayloadEvent ipPayload;
     ipPayload.dataLength = 0;
 
-    events[0].set<DemuxFilterEvent::Tag::ipPayload>(ipPayload);
+    events.push_back(
+            DemuxFilterEvent::make<DemuxFilterEvent::Tag::ipPayload>(std::move(ipPayload)));
 }
 
 void Filter::createTemiEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterTemiEvent temi;
     temi.pts = 1;
     temi.descrTag = 2;
     temi.descrData = {3};
 
-    events[0].set<DemuxFilterEvent::Tag::temi>(temi);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::temi>(std::move(temi)));
 }
 
 void Filter::createMonitorEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
     DemuxFilterMonitorEvent monitor;
     monitor.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(ScramblingStatus::SCRAMBLED);
-    events[0].set<DemuxFilterEvent::Tag::monitorEvent>(monitor);
+
+    events.push_back(
+            DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(std::move(monitor)));
 }
 
 void Filter::createRestartEvent(vector<DemuxFilterEvent>& events) {
-    events.resize(1);
-
-    events[0].set<DemuxFilterEvent::Tag::startId>(1);
+    events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::startId>(1));
 }
 
 }  // namespace tuner
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index a5adf4c..8388c98 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -68,6 +68,8 @@
 
     bool hasCallbackRegistered() const;
 
+    void flushEvents();
+
   private:
     void start();
     void stop();
@@ -75,6 +77,9 @@
     void threadLoop();
     void threadLoopOnce();
 
+    // function needs to be called while holding mLock
+    bool isDataSizeDelayConditionMetLocked();
+
     static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event);
 
   private:
@@ -82,16 +87,15 @@
     std::thread mCallbackThread;
     std::atomic<bool> mIsRunning;
 
-    // mLock protects mCallbackBuffer, mCv, and mDataLength
+    // mLock protects mCallbackBuffer, mIsConditionMet, mCv, mDataLength,
+    // mTimeDelayInMs, and mDataSizeDelayInBytes
     std::mutex mLock;
     std::vector<DemuxFilterEvent> mCallbackBuffer;
+    bool mIsConditionMet;
     std::condition_variable mCv;
     int mDataLength;
-
-    // both of these need to be atomic (not just mTimeDelayInMs) as this class
-    // needs to be threadsafe.
-    std::atomic<int> mTimeDelayInMs;
-    std::atomic<int> mDataSizeDelayInBytes;
+    int mTimeDelayInMs;
+    int mDataSizeDelayInBytes;
 };
 
 class Filter : public BnFilter {
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index f9e697e..77d20e2 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -607,6 +607,13 @@
                         status.set<FrontendStatus::interleaving>(interleaves);
                         break;
                     }
+                    case FrontendType::ISDBT: {
+                        interleave.set<FrontendInterleaveMode::Tag::isdbt>(
+                                FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0); // value = 1 << 1
+                        interleaves.push_back(interleave);
+                        status.set<FrontendStatus::interleaving>(interleaves);
+                        break;
+                    }
                     default:
                         break;
                 }
@@ -660,6 +667,15 @@
                 status.set<FrontendStatus::isShortFrames>(true);
                 break;
             }
+            case FrontendStatusType::ISDBT_MODE: {
+                status.set<FrontendStatus::isdbtMode>(FrontendIsdbtMode::AUTO);
+                break;
+            }
+            case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+                status.set<FrontendStatus::partialReceptionFlag>(
+                        FrontendIsdbtPartialReceptionFlag::AUTO);
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index 8468929..badb08f 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -119,6 +119,10 @@
             .coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
                            (int)FrontendIsdbtCoderate::CODERATE_6_7,
             .guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
+            .timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
+                                 (int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
+            .isSegmentAuto = true,
+            .isFullSegment = true,
     };
     capsIsdbt.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
     mFrontendCaps[5] = capsIsdbt;
@@ -131,6 +135,9 @@
             FrontendStatusType::GUARD_INTERVAL,
             FrontendStatusType::TRANSMISSION_MODE,
             FrontendStatusType::ISDBT_SEGMENTS,
+            FrontendStatusType::ISDBT_MODE,
+            FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
+            FrontendStatusType::INTERLEAVINGS,
     };
     mFrontendStatusCaps[5] = statusCaps;
 
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
index fa09456..d0248c2 100644
--- a/tv/tuner/aidl/default/tuner-default.rc
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index c53adb2..a5acdc1 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -23,6 +23,33 @@
 
 using ::aidl::android::hardware::common::NativeHandle;
 
+::ndk::ScopedAStatus FilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& events) {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    // Temprarily we treat the first coming back filter data on the matching pid a success
+    // once all of the MQ are cleared, means we got all the expected output
+    readFilterEventsData(events);
+    mPidFilterOutputCount++;
+    mMsgCondition.signal();
+
+    // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor
+    // that cannot be copied.
+    for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) {
+        auto it = mFilterEventPromises.find(e.getTag());
+        if (it != mFilterEventPromises.cend()) {
+            it->second.set_value(std::move(e));
+            mFilterEventPromises.erase(it);
+        }
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) {
+    // Note: this currently only supports one future per DemuxFilterEvent::Tag.
+    mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>();
+    return mFilterEventPromises[tag].get_future();
+}
+
 void FilterCallback::testFilterDataOutput() {
     android::Mutex::Autolock autoLock(mMsgLock);
     while (mPidFilterOutputCount < 1) {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index c965d95..6258bac 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -24,7 +24,9 @@
 #include <log/log.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
+#include <future>
 #include <map>
+#include <unordered_map>
 
 #include <fmq/AidlMessageQueue.h>
 
@@ -58,15 +60,9 @@
 
 class FilterCallback : public BnFilterCallback {
   public:
-    virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override {
-        android::Mutex::Autolock autoLock(mMsgLock);
-        // Temprarily we treat the first coming back filter data on the matching pid a success
-        // once all of the MQ are cleared, means we got all the expected output
-        readFilterEventsData(events);
-        mPidFilterOutputCount++;
-        mMsgCondition.signal();
-        return ::ndk::ScopedAStatus::ok();
-    }
+    virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
+
+    std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag);
 
     virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
         return ::ndk::ScopedAStatus::ok();
@@ -89,6 +85,7 @@
     int32_t mFilterId;
     std::shared_ptr<IFilter> mFilter;
 
+    std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises;
     native_handle_t* mAvSharedHandle = nullptr;
     uint64_t mAvSharedMemSize = -1;
 
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 77add8e..6204803 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -171,7 +171,8 @@
     }
 
     EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
-    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    if (type == FrontendScanType::SCAN_BLIND)
+        EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
     mScanMessageReceived = false;
     mScanMsgProcessed = true;
 }
@@ -387,6 +388,16 @@
                             expectStatuses[i].get<FrontendStatus::Tag::isShortFrames>());
                 break;
             }
+            case FrontendStatusType::ISDBT_MODE: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isdbtMode>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::isdbtMode>());
+                break;
+            }
+            case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 85e5c68..88890e4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -640,6 +640,57 @@
     testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
 }
 
+// TODO: move boilerplate into text fixture
+TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) {
+    description("Test filter delay hint.");
+
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFilterTests.setDemux(demux);
+
+    const auto& filterConf = filterMap[live.ipFilterId];
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+
+    auto filter = mFilterTests.getFilterById(filterId);
+
+    auto delayValue = std::chrono::milliseconds(5000);
+    FilterDelayHint delayHint;
+    delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
+    delayHint.hintValue = delayValue.count();
+
+    auto status = filter->setDelayHint(delayHint);
+    ASSERT_TRUE(status.isOk());
+
+    auto startTime = std::chrono::steady_clock::now();
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+    auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+    auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload);
+
+    // block and wait for callback to be received.
+    ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready);
+    auto duration = std::chrono::steady_clock::now() - startTime;
+    ASSERT_GE(duration, delayValue);
+
+    // cleanup
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
 TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
     description("Feed ts data from playback and configure Ts section filter to get output");
     if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 006bf17..5a72ba4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -52,7 +52,7 @@
 const int32_t FMQ_SIZE_4M = 0x400000;
 const int32_t FMQ_SIZE_16M = 0x1000000;
 
-const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml";
+const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
 
 #define FILTER_MAIN_TYPE_BIT_COUNT 5
 
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 08270d6..7ccf31a 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -956,6 +956,7 @@
         }
         auto av = filterConfig.getFirstAvFilterSettings_optional();
         settings.isPassthrough = av->getIsPassthrough();
+        settings.isSecureMemory = av->getIsSecureMemory();
         return settings;
     }
 
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index d026bf9..6c637a4 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -5,9 +5,11 @@
     ctor public AvFilterSettings();
     method @Nullable public short getAudioStreamType_optional();
     method @Nullable public boolean getIsPassthrough();
+    method @Nullable public boolean getIsSecureMemory();
     method @Nullable public short getVideoStreamType_optional();
     method public void setAudioStreamType_optional(@Nullable short);
     method public void setIsPassthrough(@Nullable boolean);
+    method public void setIsSecureMemory(@Nullable boolean);
     method public void setVideoStreamType_optional(@Nullable short);
   }
 
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
new file mode 100644
index 0000000..8a6229e
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<!-- The Sample Tuner Testing Configuration.
+    Name the customized xml with "tuner_vts_config.xml" and push into the device
+    "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
+    The version section contains a “version” tag in the form “major.minor” e.g. version=”1.0”
+    This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- Hardware Configuration section contains the configurations of all the hardwares
+        that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+        under test has its required/optional hardwares. The ids configured in the
+        "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+    <hardwareConfiguration>
+        <!-- Frontends section:
+            This section contains configurations of all the frontends that would be used
+                in the tests.
+                - This section is optional and can be skipped to use the default fe settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default frontend settings using id="FE_DEFAULT".
+                - The users can configure 1 or more frontend elements in the frontends sections.
+
+            Each frontend element contain the following attributes:
+                "id": unique id of the frontend that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the frontend type. The enums are defined in the xsd.
+                "isSoftwareFrontend": if the test environment is using hardware or software
+                    frontend. If using software, a ts input file path needs to be configured.
+                "softwareFeInputPath": used as the source of the software frontend.
+                "connectToCicamId": if the device supports frontend connecting to cicam, the target
+                    cicam id needs to be configured here. Supported in Tuner 1.1 or higher.
+                "frequency": the frequency used to configure tune and scan.
+                "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+            Each frontend element also contains one and only one type-related "frontendSettings".
+                - The settings type should match the frontend "type" attribute.
+                - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
+                - This is optional and skipping the settings would pass a setting with frequency
+                    config only to the hal.
+        -->
+        <frontends>
+            <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+                <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+            </frontend>
+            <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+            </frontend>
+        </frontends>
+        <!-- Filter section:
+            This section contains configurations of all the filters that would be used in the tests.
+                - This section is optional and can be skipped to use the default filter settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default filter settings using
+                - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+                - The users can configure 1 or more filter elements in the filters sections.
+
+            Each filter element contain the following attributes:
+                "id": unique id of the filter that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "mainType": the main filter type. The enums are defined in the xsd.
+                "subType": the sub filter type. The enums are defined in the xsd.
+                "bufferSize": the buffer size of the filter in hex.
+                "pid": the pid that would be used to configure the filter.
+                "useFMQ": if the filter uses FMQ.
+
+            Each filter element also contains at most one type-related "filterSettings".
+                - The settings type should match the filter "subType" attribute.
+                - For example, when filter subType is audio or video, the avFilterSettings can be
+                    configured.
+                - This is optional and skipping the settings would pass a setting with tpid config
+                    only to the hal.
+        -->
+        <filters>
+            <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+                    bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false" isSecureMemory="false">
+                    <audioStreamType>2</audioStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+                    bufferSize="16777216" pid="256" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false" isSecureMemory="false">
+                    <videoStreamType>2</videoStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+                    bufferSize="16777216" pid="257" useFMQ="false">
+                <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+            </filter>
+            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+                <ipFilterConfig ipCid="1">
+                    <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
+                    <destIpAddress isIpV4="true" ip="192 168 1 1"/>
+                </ipFilterConfig>
+            </filter>
+        </filters>
+        <!-- Dvr section:
+            This section contains configurations of all the dvrs that would be used in the tests.
+                - This section is optional and can be skipped if DVR is not supported.
+                - The users can configure 1 or more dvr elements in the dvrs sections.
+
+            Each dvr element contain the following attributes:
+                "id": unique id of the dvr that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the dvr type.
+                "bufferSize": the dvr buffer size.
+                "statusMask": register callbacks of specific status.
+                "lowThreshold": the dvr status low threshold.
+                "highThreshold": the dvr status high threshold.
+                "dataFormat": the dvr data format.
+                "packetSize": the dvr packet size.
+                "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+        -->
+        <dvrs>
+            <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+            <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188"/>
+            <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+        </dvrs>
+    </hardwareConfiguration>
+
+    <!-- Data flow configuration section connects each data flow under test to the ids of the
+        hardwares that would be used during the tests. -->
+    <dataFlowConfiguration>
+        <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+                            audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                            videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                            ipFilterConnection="FILTER_IP_IP_0"
+                            dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+        <scan frontendConnection="FE_DEFAULT"/>
+        <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
+                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                     videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
+        <dvrRecord hasFrontendConnection="true"
+                   frontendConnection="FE_DEFAULT"
+                   recordFilterConnection="FILTER_TS_RECORD_0"
+                   dvrRecordConnection="DVR_RECORD_0"
+                   dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+    </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 6a04b7e..fc2827f 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -191,7 +191,7 @@
             <xs:enumeration value="IP"/>
             <xs:enumeration value="NTP"/>
             <xs:enumeration value="IP_PAYLOAD"/>
-            <xs:enumeration value="PAYLOAD_THROUGH"/>            
+            <xs:enumeration value="PAYLOAD_THROUGH"/>
         </xs:restriction>
     </xs:simpleType>
 
@@ -220,6 +220,7 @@
             <xs:element name="videoStreamType" type="xs:unsignedByte"/>
         </xs:choice>
         <xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
+        <xs:attribute name="isSecureMemory" type="xs:boolean" use="required"/>
     </xs:complexType>
     <xs:complexType name="sectionFilterSettings">
         <xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/>
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 5f56fe0..4bed2c7 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,11 +21,21 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "android.hardware.usb@1.0-service.xml",
+    srcs: ["android.hardware.usb@1.0-service.xml"],
+}
+
+filegroup {
+    name: "android.hardware.usb@1.0-service.rc",
+    srcs: ["android.hardware.usb@1.0-service.rc"],
+}
+
 cc_binary {
     name: "android.hardware.usb@1.0-service",
     defaults: ["hidl_defaults"],
-    init_rc: ["android.hardware.usb@1.0-service.rc"],
-    vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
+    init_rc: [":android.hardware.usb@1.0-service.rc"],
+    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
diff --git a/usb/1.0/default/apex/Android.bp b/usb/1.0/default/apex/Android.bp
new file mode 100644
index 0000000..ee50fdf
--- /dev/null
+++ b/usb/1.0/default/apex/Android.bp
@@ -0,0 +1,59 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.usb.key",
+    public_key: "com.android.hardware.usb.avbpubkey",
+    private_key: "com.android.hardware.usb.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.usb.certificate",
+    certificate: "com.android.hardware.usb",
+}
+
+genrule {
+    name: "com.android.hardware.usb.rc-gen",
+    srcs: [":android.hardware.usb@1.0-service.rc"],
+    out: ["com.android.hardware.usb.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.usb.rc",
+    src: ":com.android.hardware.usb.rc-gen",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.usb",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.usb.key",
+    certificate: ":com.android.hardware.usb.certificate",
+    updatable: false,
+    soc_specific: true,
+    use_vndk_as_stable: true,
+    binaries: ["android.hardware.usb@1.0-service"],
+    prebuilts: [
+        "com.android.hardware.usb.rc",
+        "android.hardware.usb.accessory.prebuilt.xml",
+        "android.hardware.usb.host.prebuilt.xml",
+    ],
+    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
new file mode 100644
index 0000000..0302d63
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/1.0/default/apex/com.android.hardware.usb.pem
new file mode 100644
index 0000000..e1e57da
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAwdimmHgIZHrep3H3YfVaNYEAGg45LUEPIiwHV6aIC9V7zjBS
+SftD30Z21jGyk7hmtas6WMI2vRBDNGrZWDgPeiEQoxXQinuU4Ug5S5X2F8LpWs0y
+ZeNFwQkqZwqGdQlkmy8upfb6T7rDxqRv+C0AtGP1r4r36+Xh5ld5stVaMK0UNhZt
+VW0nQAxyeJL3tm0zfiEA9Zu7FF2IyHm+bo9+eJ7WXfjiJfkclLgqlX3ec2cvVqAf
+NHisj18PEd/qtC64b+FnkgbsdHzWbo8HW5x4STkGXNnH+O3dvkWBX60MOfywfZFw
++yaz5mt7K+ft/V4UA7zKiAEFM+J1lND9/UMJnd0XMYYtcRQF8lmu4dlcjfbbAm0k
+VgoUEsizIeMPLrMj837uVloKKzIXmPsVsfMarP/MrX6TJfzdUhdm01pVO1g0wtHJ
+J3eYQsEnOI7RjL+uZDQvPWAnr71pvacn66PAJC1UPulEEla5lhd30RDItbJkngXp
+3UggW32ZOQt3Oc8P0eo9SCnBlHtCVr8wfxAbxCoPR9qIdX3azkQRqcKqGbBbPnkc
+hSCzeIofUkYGibfbZg4k1yY82xEqZuN7J1zycoGP4wyhXeRLTRWxfPR5dxxmQZaS
+67A1LWrYvAzF8Rd44VMRlI/Qk6zuBsL01j2dfBqit+le+viQmTYb3BpV+1kCAwEA
+AQKCAgAmSfX2LddyiXaLWo6DsePkp5tuihqvHqevl0TIAmPi+oMe4hqO9GueoZt9
+iYl9djILdkvrFkmbpKexpd1SeJhOBlPz8q4jfG+W5B41GOToIp7XSarHx1GS5I2U
+ltaiLX3KzVIIhDVDJF/hT7+yJKl7+DaiOu/nj5vEVMj8EvpinP1eBaYI9quHEi5W
+NKlrRjyikEBRQzZ7ulH3T1zXF87iYnVzUGLTH1aO5aW7q4YSA3KtSKmBQsjK9PrU
+DAefGY9iwgIkLOvtwm7UnbnVVZ3I0NO56WZ/e/SNzcrVLCg7F/eAhgbsBOQKAnbs
+4D35CuknJ9ZVcOYnLncNMw7IRMKULKYLAuLLN1X33y22qaVxYA42rq13mZrijlua
+CMQ2Ur+GNcq8OI3mRDO38yKeJ5b4885LQdlrXXyoGnSjlkU5n8U9Jw6q2rZGiWlk
+4Q71g+KUl0rtXSnFSIJLNTK6Cd3ETStxswLvvCvfLTrRQcO8f2SdVxblmsc9eCDs
+JUxz6Sahkpb9hsY8fozu6laXC/5Ezy0TinRgGjQM/DQqbXtFXgse56mDxzSho5oh
+Spy3X7Q/v4VUtrSKsEZEIEVWCpplzVULpHenCDbU58rHyEcS7ew+kwlfHC73iEhX
+HPujSIKvStO7yCEeY6IdhON8iVX34uvQeAgEe4+rehQHLZUg0QKCAQEA9AS3imKF
+yEt0yNRLcdXSqYkak+OM2kfhBBcLndCT7Terr6yluv/SkPGYjUbmr2XiygMv8IwO
+8f+KbWsNwYCaB22HVYVGL0oUYAlCvWhnia3Iwn6ZZuXuJv5mmfqt/GMlaIfohNLy
+zI2OlcpcAuRfNlenjNyd+inxwdXL28Z86kbabnUlijgqpu4KFOYOlxbTRv93IlfM
+Ico1pZkLS1glDMFLetF+IWq4zqpXrdgNUk1KX3sofOCfZQnlWFrrHbXJPCgPAtlv
+xP4dmJQgtWkWwxUlelfz34LcCUVX2aTlgKjuvgvyCt2ZPWixXbDtjsCBTn3xBhoY
+kDp2OyMC+d543QKCAQEAy11GpYOQvTMKbV07EmN9jTRYg7gRrxsT3Kd4Xy+NpIY8
+v6J5Keeppk9t6WBrJi2cQU/EoHcd3fRkWMnWMNorZDiCu34VG5bfa4pTqnSLdLC4
+/e5UHdHqCy9deAwhlHYWbAx0KnxXWGxkq05dXvQsVuOtAs528NcujnLpwDONQt5P
+e3RIZmOOjr+7rqGp3vA9SuNOINOQpeKxQT6GRGw4mlYofdwOPaE1wCsO8vQCNmCJ
+DEfdm+hWjTLAV2IBCfi5BKRsIAXrABPzkzDeLGDmaQkJTDpK8UQcrFnqItGeo+yl
+fDjxA0zAPWYGcyXcXbtvayX+zCk/SKwQABqUtaumrQKCAQEA0mdizwsGqd8OMsCC
+0QP64j4a0Zvqbqh9yCYK2Sfo9SkEe7SVLnm5WUtIK8EP1fs3ItK+ul454MZj2Nbv
+BINbzL3PbJk/HDV2/hveFS154UgcjD/XC9eEktDXLTvuW2ot7kUJ48V0n5YLdPMI
+hWHfCx9nlFkCSptyHp23aqhqOyOe4pFWLikh9c/Yl46K1BJVWKmcUtt7Y0NVIJWn
+HG9Dew0MhTkv1aaM9X4Bnh9l1SpZz5yFG7AfIGL5A0dZ5cNCYgF0eBN+gVBPuqk2
+ztVvUATizOwblwThr4jAKCU70sVXHj10lZPftwiXrt6I54brt/92HLnRpkMSgQk+
+Xq9KbQKCAQAXxPM47UPBmXGijr8UyyQlmPSvkJggi12q8LgVCA3aKQZ4r5jR2Q3v
+LmF+YZKkh7g3ugcValbHVoVUC2NJmnZv5FsDZx04eE3s1+Inji+ul+lHZM/YHGzq
+mcKnAWP7YkIEpv/850OeRi0OCL7JFmkITtwt88vbIouCgtPnbx8XrbxEhbbgoMpM
+zQQ2yRZ9xD6lviOnmpLRkMl/ArvWy39iKqfY7huMAIezylSY+QQ5LtdV5CB21JUp
+M8FfdUkBzVxyunUY2Rg6jhpuHcwaC8lihXfcvQN9Z6SiUHAZWb7dEg/VkSI6bIIb
+qw0d8FLtcbb4IxzA6CFJcTL9kB3JjiKRAoIBAQC15t3mQHb9iCM4P4U9fpR4syvN
+46vDMhtj3vejerzOro2R7UUCJDvT59DrCQvtKO/ZCyhdTyuyResu6r1vbwq3KWiB
+i0RIeW87cKgJRr6w+KivB+a805WfI9zNRz778b7ajEpBkOs4vRPWu6S1306tdvgM
+Dhj7GT9UFh/k7pNuoSbiuaPUqgZRP55nzgj/FoIN985wnxo/ugckSqZ1bFGFXhYt
+zfIdFvPkf1BlLCnLTE8yESsJ3P37Gfj2XRv9h2I2/8qAGZniKtbVWHlu+5LDJf6V
+x9VpDAH2ZQAqRC3za3gfTjMsglYi7mUDeMYlB4osURNt7jDtElEmsto7AAkI
+-----END RSA PRIVATE KEY-----
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/1.0/default/apex/com.android.hardware.usb.pk8
new file mode 100644
index 0000000..9f3f39b
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
new file mode 100644
index 0000000..210c30d
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1TCCA70CFFEdsyLGoTRk+VIzqb6aDl1tXeuZMA0GCSqGSIb3DQEBCwUAMIGl
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEhMB8GA1UEAwwYY29t
+LmFuZHJvaWQuaGFyZHdhcmUudXNiMCAXDTIxMTExNzIyMzAwM1oYDzQ3NTkxMDE0
+MjIzMDAzWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAU
+BgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsM
+B0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20xITAf
+BgNVBAMMGGNvbS5hbmRyb2lkLmhhcmR3YXJlLnVzYjCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAM2E0E9ubNU/or7r9UIcFrC4l7CeM0HwtwSjTUKV1Z9K
+7rPFoUPE3cQ+cResnWQay8IGnomLYptAIMe8sLCC83LwU1ucTihxX87qq2W3V14w
+U4AkqDzNvYqKiD3yz9WofKxcu7ut8+1O4Pvp11X8UXuy5kNzf8WGpGB04k6U6KtA
+q8+U8+4h9h1Uvhaa0AeG9Yp22LzRLTb3J+eCoGHJnjoXYsd9T/gvedyXKkuf0lWB
+b3Aor3/CQrpdCW2/iJbuASdBdfilpQShaagxy2wmQsYxnT8ZWf+tIDYjg3xqqVPl
+GChFwCQBdaTuLI/k9gbaXkSxuzRkp5wc/ELhYbkhIS25yefAF2C6num++AHQBh1+
+qO0fHztsK80c5cVoDPWu17/nP7y3QloRyLFUrL3hVW1RQaFwE2Hmv4H0UwVAsleU
+ZIsz2ifTjiSl/tnkFTx0I6BVk7T87QhO3WXN4v6VDYZKeD4gQYS0NfwplahejrFw
+s3EcwKgt6f0KlIpzoEQBmNQBXxsRgL31GWCwCszb7+VrTMzgUpO41R3PyewbeaZk
+S/SHyEOwyf0WIvnZhZ/5CNd9qirClu6jS8kdLvwC2qA25VqSPw126EX1e2xUqm02
+C/6c7JDVocuQhvsJOnnpZt68Iwgw9g/xLCLA9RszH9ccRctZqRnzHB1AjTrBOq0P
+AgMBAAEwDQYJKoZIhvcNAQELBQADggIBAELbSot2Io/JZIYLTxgeReI4lk1KUzf8
+fGlDNlRm+goxOHXWQgvXgiftwM9IOB+H+EtNHAA9Q6ojAmfRe6rZC4p0ZxWOamtR
+V+pQj0c6Zvx8HJPMQdyoHx538iNXM093s2wnf+QuACb3BnvkK7uuLGAlIzWdImtL
+DKKFN05nppViY04tGP5HgT57b7YGwdkEp6euCJcyWIKjlyEH/bwTWM8ws/Px6uhw
++5W2K7KrBsdRKPBF7qwXoS8Ak8pS5de9Xd7mbGBLaUtjsZ0pJbq0aFpuT0GbLWUm
+wiD5Ljq3ea/2GZxbHGiXQ2yNjFSd/jpuxDnnm99t7+HGw1v5Jld+hUVqXXfVNhWe
+hUKIv5TOk1nttNdsaLyDtxyt22JX7NnoPM0MqrkYwA8Xqrbv0VC8D/CVjiBC9Tce
+crhpCISNfQSkdEn/c+q/naFUvQy8oYqXkg1TjeGlcxwJOpGliYbbYT6VAwuI/ssI
+yX3Fkr8f5KhfN2aFnOpidknmLp9EyL2j5bxAtSD9xAHtczMn10uCUdLELjRB1L4f
+1qY+EjpIgK0NIFuEt9K5uZXirXq3K3eixKeJFNji3x/X8NgDALSdnT8JIlSg4DMg
+iWupLrQ9CSHMlgh5P43ALamiRIHQNqEwgj8OIGzsvQTSLbRjbPWYcDZa+Q1hosiA
+Fv7vjDI6oySM
+-----END CERTIFICATE-----
diff --git a/usb/1.0/default/apex/file_contexts b/usb/1.0/default/apex/file_contexts
new file mode 100644
index 0000000..bc84ac4
--- /dev/null
+++ b/usb/1.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\.usb@1\.0-service    u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
new file mode 100644
index 0000000..6a1095f
--- /dev/null
+++ b/usb/1.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.usb",
+  "version": 1
+}
diff --git a/uwb/aidl/vts/OWNERS b/uwb/OWNERS
similarity index 100%
rename from uwb/aidl/vts/OWNERS
rename to uwb/OWNERS
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 0d1ebc2..99fd094 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -35,6 +35,7 @@
                 "//apex_available:platform",
                 "com.android.uwb",
             ],
+            min_sdk_version: "current",
         },
     },
 }
@@ -53,9 +54,6 @@
             ],
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
                 "com.android.uwb",
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
similarity index 84%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 6eadbb7..7e3be56 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -2,10 +2,10 @@
  * 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 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
+ *        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,
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbAndroidCapabilities {
+  POWER_STATS_QUERY = 1,
+  ANTENNAE_INTERLEAVING = 2,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
similarity index 83%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index 6eadbb7..cd2e122 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -2,10 +2,10 @@
  * 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 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
+ *        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,
@@ -31,9 +31,9 @@
 // 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;
-@Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGidAndroidOids {
+  ANDROID_GET_POWER_STATS = 0,
+  ANDROID_SET_COUNTRY_CODE = 1,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
similarity index 87%
copy from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
index 6eadbb7..30a0a1b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -2,10 +2,10 @@
  * 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 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
+ *        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,
@@ -31,9 +31,8 @@
 // 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;
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum SapTransferProtocol {
-  T0 = 0,
-  T1 = 1,
+enum UwbVendorSessionInitSessionType {
+  CCC = 160,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 37b7efb..f449c60 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -38,4 +38,7 @@
   CCC_UWB_CONFIG_ID = 164,
   CCC_PULSESHAPE_COMBO = 165,
   CCC_URSK_TTL = 166,
+  NB_OF_RANGE_MEASUREMENTS = 227,
+  NB_OF_AZIMUTH_MEASUREMENTS = 228,
+  NB_OF_ELEVATION_MEASUREMENTS = 229,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
index 7074753..c4cb47b 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
@@ -40,6 +40,7 @@
   void open(in android.hardware.uwb.IUwbClientCallback clientCallback);
   void close();
   void coreInit();
-  int getSupportedVendorUciVersion();
+  int getSupportedAndroidUciVersion();
+  long getSupportedAndroidCapabilities();
   int sendUciMessage(in byte[] data);
 }
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
old mode 100755
new mode 100644
index 9530af4..0c98611
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -49,14 +49,24 @@
      */
     void coreInit();
 
-     /**
-      * Supported version of vendor UCI specification.
-      *
-      * This corresponds to the version of the "android.hardware.uwb.fira_android" types-only
-      * package included in the HAL implementation. This vendor params/commands package will be
-      * updated on a different cadence to the main UWB HAL interface package.
-      */
-    int getSupportedVendorUciVersion();
+    /**
+     * Supported version of vendor UCI specification.
+     *
+     * @return Returns the version of the "android.hardware.uwb.fira_android" types-only
+     * package included in the HAL implementation. This vendor params/commands package will be
+     * updated on a different cadence to the main UWB HAL interface package.
+     */
+    int getSupportedAndroidUciVersion();
+
+    /**
+     * Mechanism to allow HAL implementation to optionally expose features that are defined
+     * in the "android.hardware.uwb.fira_android" types-only package.
+     *
+     * @return Returns the bitmask of capabilities
+     * (android.hardware.uwb.fira_android.UwbAndroidCapabilities) that is supported by the
+     * HAL implementation.
+     */
+    long getSupportedAndroidCapabilities();
 
     /**
      * Write the UCI message to the UWB Subsystem.
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
new file mode 100644
index 0000000..0af99e0
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.uwb.fira_android;
+
+/**
+ * Android specific capabilities should be defined here.
+ *
+ * For any features enabled via the FIRA vendor commands for Android, use this bitmask
+ * to allow devices to expose the features supported by the HAL implementation.
+ *
+ */
+@VintfStability
+@Backing(type="long")
+enum UwbAndroidCapabilities {
+    POWER_STATS_QUERY = 0x1,
+    ANTENNAE_INTERLEAVING = 0x2,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
new file mode 100644
index 0000000..1dfcd6f
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.uwb.fira_android;
+
+/**
+ * Android specific vendor command OIDs should be defined here.
+ *
+ */
+@VintfStability
+@Backing(type="byte")
+enum UwbVendorGidAndroidOids {
+    // Used by the command and response to get UWB power related stats.
+    // Supported only if the value returned by getSupportedAndroidCapabilities()
+    // has the bit of UwbAndroidCapabilities.POWER_STATS_QUERY set to 1.
+    ANDROID_GET_POWER_STATS = 0x0,
+    // Used to set the current regulatory country code (determined usinag
+    // SIM or hardcoded by OEM).
+    ANDROID_SET_COUNTRY_CODE = 0x1,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
new file mode 100644
index 0000000..1e2c817
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.uwb.fira_android;
+
+/**
+ * Android specific session type set in UCI command:
+ * GID: 0001b (UWB Session config Group)
+ * OID: 000000b (SESSION_INIT_CMD)
+ *
+ * Note: Refer to Table 13 of the UCI specification for the other
+ * session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum UwbVendorSessionInitSessionType {
+    /** Added in vendor version 0. */
+    CCC = 0xA0,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 850e2da..f5e02c0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -29,9 +29,29 @@
 enum UwbVendorSessionSetAppConfigCmdParams {
     /** CCC params for ranging start */
 
-    /** Added in vendor version 0. */
+    /**
+     * Added in vendor version 0.
+     * Range 0xA0 - 0xDF reserved for CCC use.
+     */
     CCC_RANGING_PROTOCOL_VER = 0xA3,
     CCC_UWB_CONFIG_ID = 0xA4,
     CCC_PULSESHAPE_COMBO = 0xA5,
     CCC_URSK_TTL = 0xA6,
+
+    /**
+     * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
+     * In Android, this range is reserved by the Android platform for Android-specific
+     * app config cmd params.
+     * Vendors must not define additional app config cmd params in this range.
+     */
+
+    /**
+     * Added in vendor version 0.
+     * Interleaving ratio if AOA_RESULT_REQ is set to 0xF0.
+     * Supported only if the value returned by getSupportedAndroidCapabilities()
+     * has the bit of UwbAndroidCapabilities.ANTENNAE_INTERLEAVING set to 1.
+     */
+    NB_OF_RANGE_MEASUREMENTS = 0xE3,
+    NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
+    NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
 }
diff --git a/uwb/aidl/default/OWNERS b/uwb/aidl/default/OWNERS
deleted file mode 100644
index c4ad416..0000000
--- a/uwb/aidl/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 1042770
-include platform/packages/modules/Uwb:/OWNERS
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
index fe64fa7..10dbdb6 100644
--- a/uwb/aidl/default/uwb_chip.cpp
+++ b/uwb/aidl/default/uwb_chip.cpp
@@ -17,7 +17,8 @@
 #include "uwb.h"
 
 namespace {
-constexpr static int kVendorUciVersion = 1;
+constexpr static int32_t kAndroidUciVersion = 1;
+constexpr static int64_t kAndroidCapabilities = 0;
 }
 
 namespace android {
@@ -50,8 +51,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus UwbChip::getSupportedVendorUciVersion(int32_t* version) {
-    *version = kVendorUciVersion;
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
+    *version = kAndroidUciVersion;
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidCapabilities(int64_t* capabilities) {
+    *capabilities = kAndroidCapabilities;
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
index ef1d5b6..ca97120 100644
--- a/uwb/aidl/default/uwb_chip.h
+++ b/uwb/aidl/default/uwb_chip.h
@@ -37,7 +37,8 @@
     ::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
     ::ndk::ScopedAStatus close() override;
     ::ndk::ScopedAStatus coreInit() override;
-    ::ndk::ScopedAStatus getSupportedVendorUciVersion(int32_t* version) override;
+    ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
+    ::ndk::ScopedAStatus getSupportedAndroidCapabilities(int64_t* capabilities) override;
     ::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
                                         int32_t* bytes_written) override;
 
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 9ac2678..3820c0f 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -166,15 +166,23 @@
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
 }
 
-TEST_P(UwbAidl, ChipGetSupportedVendorUciVersion) {
+TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
     const auto iuwb_chip = getAnyChipAndOpen();
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
 
-    int version;
-    EXPECT_TRUE(iuwb_chip->getSupportedVendorUciVersion(&version).isOk());
+    int32_t version;
+    EXPECT_TRUE(iuwb_chip->getSupportedAndroidUciVersion(&version).isOk());
     EXPECT_GT(version, 0);
 }
 
+TEST_P(UwbAidl, ChipGetSupportedAndroidCapabilities) {
+    const auto iuwb_chip = getAnyChipAndOpen();
+    EXPECT_TRUE(iuwb_chip->coreInit().isOk());
+
+    int64_t capabilities;
+    EXPECT_TRUE(iuwb_chip->getSupportedAndroidCapabilities(&capabilities).isOk());
+}
+
 TEST_P(UwbAidl, ChipGetName) {
     std::string chip_name = getAnyChipName();
     std::shared_ptr<IUwbChip> iuwb_chip;
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 53f8c0e..09cc21b 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -417,6 +417,9 @@
 
             if (isPrimitiveSupported) {
                 EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+                if (primitive != CompositePrimitive::NOOP) {
+                    ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
+                }
             } else {
                 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
             }
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
index 56d9c4d..6b77924 100644
--- a/weaver/aidl/default/Weaver.cpp
+++ b/weaver/aidl/default/Weaver.cpp
@@ -15,30 +15,52 @@
  */
 
 #include "Weaver.h"
+#include <array>
 
 namespace aidl {
 namespace android {
 namespace hardware {
 namespace weaver {
 
+struct Slotinfo {
+    int slot_id;
+    std::vector<uint8_t> key;
+    std::vector<uint8_t> value;
+};
+
+std::array<struct Slotinfo, 16> slot_array;
 // Methods from ::android::hardware::weaver::IWeaver follow.
 
 ::ndk::ScopedAStatus Weaver::getConfig(WeaverConfig* out_config) {
-    (void)out_config;
+    *out_config = {16, 16, 16};
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
-    (void)in_slotId;
-    (void)in_key;
-    (void)out_response;
+
+    if (in_slotId > 15 || in_key.size() > 16) {
+        *out_response = {0, {}};
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_FAILED));
+    }
+
+    if (slot_array[in_slotId].key != in_key) {
+        *out_response = {0, {}};
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_INCORRECT_KEY));
+    }
+
+    *out_response = {0, slot_array[in_slotId].value};
+
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Weaver::write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) {
-    (void)in_slotId;
-    (void)in_key;
-    (void)in_value;
+
+    if (in_slotId > 15 || in_key.size() > 16 || in_value.size() > 16)
+        return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+
+    slot_array[in_slotId].key = in_key;
+    slot_array[in_slotId].value = in_value;
+
     return ::ndk::ScopedAStatus::ok();
 }
 
diff --git a/wifi/.clang-format b/wifi/.clang-format
deleted file mode 100644
index 25ed932..0000000
--- a/wifi/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-IndentWidth: 4
\ No newline at end of file
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index d37da08..e58cf5e 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -16,9 +16,10 @@
     srcs: ["VtsHalHostapdTargetTest.cpp"],
     shared_libs: [
         "libbinder",
+        "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.wifi.hostapd-V1-cpp",
+        "android.hardware.wifi.hostapd-V1-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 92fbf50..41c54b3 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -14,33 +14,33 @@
  * limitations under the License.
  */
 #include <VtsCoreUtil.h>
-
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
-#include <android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapdCallback.h>
+#include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
+using aidl::android::hardware::wifi::hostapd::BandMask;
+using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
+using aidl::android::hardware::wifi::hostapd::ChannelParams;
+using aidl::android::hardware::wifi::hostapd::DebugLevel;
+using aidl::android::hardware::wifi::hostapd::EncryptionType;
+using aidl::android::hardware::wifi::hostapd::FrequencyRange;
+using aidl::android::hardware::wifi::hostapd::Ieee80211ReasonCode;
+using aidl::android::hardware::wifi::hostapd::IfaceParams;
+using aidl::android::hardware::wifi::hostapd::IHostapd;
+using aidl::android::hardware::wifi::hostapd::NetworkParams;
 using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::hardware::wifi::hostapd::BandMask;
-using android::hardware::wifi::hostapd::ChannelParams;
-using android::hardware::wifi::hostapd::DebugLevel;
-using android::hardware::wifi::hostapd::EncryptionType;
-using android::hardware::wifi::hostapd::FrequencyRange;
-using android::hardware::wifi::hostapd::Ieee80211ReasonCode;
-using android::hardware::wifi::hostapd::IfaceParams;
-using android::hardware::wifi::hostapd::IHostapd;
-using android::hardware::wifi::hostapd::NetworkParams;
 
 namespace {
 const unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', '2', '3', '4', '5'};
-const String16 kIfaceName = String16("wlan0");
-const String16 kPassphrase = String16("test12345");
-const String16 kInvalidMinPassphrase = String16("test");
-const String16 kInvalidMaxPassphrase = String16(
-    "0123456789012345678901234567890123456789012345678901234567890123456789");
+const std::string kIfaceName = "wlan0";
+const std::string kPassphrase = "test12345";
+const std::string kInvalidMinPassphrase = "test";
+const std::string kInvalidMaxPassphrase =
+    "0123456789012345678901234567890123456789012345678901234567890123456789";
 const int kIfaceChannel = 6;
 const int kIfaceInvalidChannel = 567;
 const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
@@ -56,8 +56,8 @@
 class HostapdAidl : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        hostapd = android::waitForDeclaredService<IHostapd>(
-            String16(GetParam().c_str()));
+        hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService(GetParam().c_str())));
         ASSERT_NE(hostapd, nullptr);
         EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
         isAcsSupport = testing::checkSubstringInCommandOutput(
@@ -77,12 +77,12 @@
         sleep(3);
     }
 
-    sp<IHostapd> hostapd;
+    std::shared_ptr<IHostapd> hostapd;
     bool isAcsSupport;
     bool isWpa3SaeSupport;
     bool isBridgedSupport;
 
-    IfaceParams getIfaceParamsWithoutAcs(String16 iface_name) {
+    IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
         IfaceParams iface_params;
         ChannelParams channelParams;
         std::vector<ChannelParams> vec_channelParams;
@@ -103,7 +103,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithBridgedModeACS(String16 iface_name) {
+    IfaceParams getIfaceParamsWithBridgedModeACS(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].enableAcs = true;
         iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -121,7 +121,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcs(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].enableAcs = true;
         iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -131,7 +131,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcsAndFreqRange(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcsAndFreqRange(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithAcs(iface_name);
         FrequencyRange freqRange;
         freqRange.startMhz = 2412;
@@ -143,7 +143,8 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(String16 iface_name) {
+    IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
+        std::string iface_name) {
         IfaceParams iface_params =
             getIfaceParamsWithAcsAndFreqRange(iface_name);
         iface_params.channelParams[0].acsChannelFreqRangesMhz[0].startMhz =
@@ -153,7 +154,7 @@
         return iface_params;
     }
 
-    IfaceParams getIfaceParamsWithInvalidChannel(String16 iface_name) {
+    IfaceParams getIfaceParamsWithInvalidChannel(std::string iface_name) {
         IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
         iface_params.channelParams[0].channel = kIfaceInvalidChannel;
         return iface_params;
@@ -215,11 +216,37 @@
     NetworkParams getInvalidSaeNwParams() {
         NetworkParams nw_params = getOpenNwParams();
         nw_params.encryptionType = EncryptionType::WPA3_SAE;
-        nw_params.passphrase = String16("");
+        nw_params.passphrase = "";
         return nw_params;
     }
 };
 
+class HostapdCallback : public BnHostapdCallback {
+   public:
+    HostapdCallback() = default;
+    ::ndk::ScopedAStatus onApInstanceInfoChanged(
+        const ::aidl::android::hardware::wifi::hostapd::ApInfo &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onConnectedClientsChanged(
+        const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onFailure(const std::string &) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+/**
+ * Register callback
+ */
+TEST_P(HostapdAidl, RegisterCallback) {
+    std::shared_ptr<HostapdCallback> callback =
+        ndk::SharedRefBase::make<HostapdCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(hostapd->registerCallback(callback).isOk());
+}
+
 /**
  * Adds an access point with PSK network config & ACS enabled.
  * Access point creation should pass.