Merge "KeyMint: Test Ecdsa key generation without curve"
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index ec16b02..e5ed844 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -17,6 +17,7 @@
 #include <array>
 #include <string>
 
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 
 #define LOG_TAG "HidlUtils_Test"
@@ -1100,6 +1101,7 @@
 TYPED_TEST_SUITE(FilterTest, FilterTestTypeParams);
 
 TYPED_TEST(FilterTest, FilterOutNonVendorTags) {
+    SKIP_WITH_HWASAN; // b/230535046
     TypeParam emptyTags;
     EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags));
 
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index f111c01..4d6f003 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -63,11 +63,8 @@
         xmlSetGenericErrorFunc(this, errorCb);
     }
     ~Libxml2Global() {
-        // TODO: check if all those cleanup are needed
         xmlSetGenericErrorFunc(nullptr, nullptr);
-        xmlSchemaCleanupTypes();
         xmlCleanupParser();
-        xmlCleanupThreads();
     }
 
     const std::string& getErrors() { return errors; }
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 f25c391..dfc2386 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -715,7 +715,7 @@
             sink.base.channelMask.value(getConfig().base.channelMask);
             sink.ext.mix({});
             sink.ext.mix().ioHandle = helper.getIoHandle();
-            sink.ext.mix().useCase.source(toString(xsd::AudioSource::AUDIO_SOURCE_MIC));
+            sink.ext.mix().useCase.source(initMetadata.tracks[0].source);
             EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{source},
                                                     hidl_vec<AudioPortConfig>{sink},
                                                     returnIn(res, mPatchHandle)));
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index fa3ee7f..61d447d 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -34,6 +34,7 @@
 
 #include <hwbinder/IPCThreadState.h>
 
+#include <android-base/expected.h>
 #include <android-base/logging.h>
 #include <system/audio_config.h>
 
@@ -130,6 +131,33 @@
     using IDevice = ::android::hardware::audio::CPP_VERSION::IDevice;
     using IDevicesFactory = ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
 
+    static android::base::expected<std::vector<std::string>, std::string> getAllFactoryInstances() {
+        using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+        const std::string factoryDescriptor = IDevicesFactory::descriptor;
+        // Make sure that the instance is the exact minor version.
+        // Using a 7.1 factory for 7.0 test is not always possible because
+        // 7.1 can be configured via the XML config to use features that are
+        // absent in 7.0.
+        auto instances = ::android::hardware::getAllHalInstanceNames(factoryDescriptor);
+        if (instances.empty()) return instances;
+        // Use the default instance for checking the implementation version.
+        auto defaultInstance = IDevicesFactory::getService("default");
+        if (defaultInstance == nullptr) {
+            return ::android::base::unexpected("Failed to obtain IDevicesFactory/default");
+        }
+        std::string actualDescriptor;
+        auto intDescRet = defaultInstance->interfaceDescriptor(
+                [&](const auto& descriptor) { actualDescriptor = descriptor; });
+        if (!intDescRet.isOk()) {
+            return ::android::base::unexpected("Failed to obtain interface descriptor: " +
+                                               intDescRet.description());
+        }
+        if (factoryDescriptor == actualDescriptor)
+            return instances;
+        else
+            return {};
+    }
+
     virtual ~HidlTest() = default;
     // public access to avoid annoyances when using this method in template classes
     // derived from test classes
@@ -174,9 +202,11 @@
 }
 
 TEST(CheckConfig, audioPolicyConfigurationValidation) {
-    const auto factories = ::android::hardware::getAllHalInstanceNames(
-            ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
-    if (factories.size() == 0) {
+    const auto factories = HidlTest::getAllFactoryInstances();
+    if (!factories.ok()) {
+        FAIL() << factories.error();
+    }
+    if (factories.value().size() == 0) {
         GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
                         "are found.";
     }
@@ -205,11 +235,11 @@
 const std::vector<DeviceParameter>& getDeviceParameters() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories = ::android::hardware::getAllHalInstanceNames(
-                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
+        const auto factories = HidlTest::getAllFactoryInstances();
+        if (!factories.ok()) return result;
         const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
         result.reserve(devices.size());
-        for (const auto& factoryName : factories) {
+        for (const auto& factoryName : factories.value()) {
             for (const auto& deviceName : devices) {
                 if (DeviceManager::getInstance().get(factoryName, deviceName) != nullptr) {
                     result.emplace_back(factoryName, deviceName);
@@ -224,9 +254,9 @@
 const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories = ::android::hardware::getAllHalInstanceNames(
-                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
-        for (const auto& factoryName : factories) {
+        const auto factories = HidlTest::getAllFactoryInstances();
+        if (!factories.ok()) return result;
+        for (const auto& factoryName : factories.value()) {
             result.emplace_back(factoryName,
                                 DeviceManager::getInstance().getPrimary(factoryName) != nullptr
                                         ? DeviceManager::kPrimaryDevice
@@ -1209,23 +1239,30 @@
     : public OpenStreamTest<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
+        auto flags = getInputFlags();
 #if MAJOR_VERSION <= 6
         address.device = AudioDevice::IN_DEFAULT;
 #elif MAJOR_VERSION >= 7
         auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
                 getDeviceName(), getMixPortName());
+        auto& metadata = initMetadata.tracks[0];
         if (maybeSourceAddress.has_value() &&
             !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType)) {
             address = maybeSourceAddress.value();
-            auto& metadata = initMetadata.tracks[0];
             metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_UNPROCESSED);
             metadata.channelMask = getConfig().base.channelMask;
         } else {
             address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
         }
-#endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION >= 1
+        auto flagsIt = std::find(flags.begin(), flags.end(),
+                                 toString(xsd::AudioInOutFlag::AUDIO_INPUT_FLAG_ULTRASOUND));
+        if (flagsIt != flags.end()) {
+            metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_ULTRASOUND);
+        }
+#endif  // 7.1
+#endif  // MAJOR_VERSION >= 7
         const AudioConfig& config = getConfig();
-        auto flags = getInputFlags();
         testOpen(
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
                     return getDevice()->openInputStream(handle, address, config, flags,
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
index ae57125..1e73f8a 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV6_0TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
index 55dbaf1..f0e2695 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV7_0TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
index 7b33a8f..7ce1477 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV7_1TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/automotive/sv/1.0/default/Android.bp b/automotive/sv/1.0/default/Android.bp
index da974a0..82e11a8 100644
--- a/automotive/sv/1.0/default/Android.bp
+++ b/automotive/sv/1.0/default/Android.bp
@@ -29,9 +29,7 @@
     relative_install_path: "hw",
     srcs: [
         "service.cpp",
-        "SurroundViewService.cpp",
-        "SurroundView2dSession.cpp",
-        "SurroundView3dSession.cpp",
+        ":automotiveSvV1.0_sources",
     ],
     init_rc: ["android.hardware.automotive.sv@1.0-service.rc"],
     vintf_fragments: ["android.hardware.automotive.sv@1.0-service.xml"],
@@ -54,3 +52,17 @@
         "-g",
     ],
 }
+
+filegroup {
+    name: "automotiveSvV1.0_sources",
+    srcs: [
+        "SurroundViewService.cpp",
+        "SurroundView2dSession.cpp",
+        "SurroundView3dSession.cpp",
+    ],
+}
+
+cc_library_headers {
+    name: "automotiveSvV1.0_headers",
+    export_include_dirs: ["."],
+}
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..394c532
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package {
+    // 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_fuzz {
+    name: "automotiveSvV1.0_fuzzer",
+    srcs: [
+        "AutomotiveSvV1_0Fuzzer.cpp",
+        "SurroundViewStream.cpp",
+        ":automotiveSvV1.0_sources",
+    ],
+    header_libs: [
+        "automotiveSvV1.0_headers",
+    ],
+    shared_libs: [
+        "android.hardware.automotive.sv@1.0",
+        "android.hidl.allocator@1.0",
+        "libhidlbase",
+        "libutils",
+        "libhidlmemory",
+        "liblog",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 533764,
+    },
+}
diff --git a/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp
new file mode 100644
index 0000000..98834f5
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "AutomotiveSvV1_0Fuzzer.h"
+#include <SurroundViewStream.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <hidlmemory/mapping.h>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hidl::allocator::V1_0::IAllocator;
+
+constexpr uint32_t kMinConfigDimension = 0;
+constexpr uint32_t kMaxConfigDimension = 4096;
+constexpr uint32_t kVertexByteSize = (3 * sizeof(float)) + 4;
+constexpr uint32_t kIdByteSize = 2;
+constexpr size_t kMaxCharacters = 30;
+constexpr size_t kMaxVertices = 10;
+constexpr size_t kMaxCameraPoints = 10;
+constexpr size_t kMaxViews = 10;
+constexpr size_t kMaxOverlays = 10;
+constexpr size_t kMinSvBuffers = 0;
+constexpr size_t kMaxSvBuffers = 10;
+
+void SurroundViewFuzzer::invoke2dSessionAPI() {
+    sp<ISurroundView2dSession> surroundView2dSession;
+
+    while (mFuzzedDataProvider.remaining_bytes() > 0) {
+        auto surroundView2dFunc = mFuzzedDataProvider.PickValueInArray<
+                const std::function<void()>>({
+                [&]() {
+                    mSurroundViewService->start2dSession(
+                            [&surroundView2dSession](const sp<ISurroundView2dSession>& session,
+                                                     SvResult result) {
+                                if (result == SvResult::OK) {
+                                    surroundView2dSession = session;
+                                }
+                            });
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        sp<SurroundViewStream> handler =
+                                sp<SurroundViewStream>::make(surroundView2dSession);
+                        surroundView2dSession->startStream(handler);
+                        mIs2dStreamStarted = true;
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->get2dMappingInfo(
+                                []([[maybe_unused]] Sv2dMappingInfo info) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        Sv2dConfig config;
+                        config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        if (mFuzzedDataProvider.ConsumeBool()) {
+                            config.blending = static_cast<SvQuality>(
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
+                        } else {
+                            config.blending = mFuzzedDataProvider.ConsumeBool() ? (SvQuality::HIGH)
+                                                                                : (SvQuality::LOW);
+                        }
+                        surroundView2dSession->set2dConfig(config);
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->get2dConfig([&](Sv2dConfig) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        hidl_vec<Point2dInt> points2dCamera;
+                        const size_t camPoints = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                1, kMaxCameraPoints);
+                        points2dCamera.resize(camPoints);
+                        for (size_t i = 0; i < camPoints; ++i) {
+                            points2dCamera[i].x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                            points2dCamera[i].y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        }
+
+                        hidl_vec<hidl_string> cameraIds;
+                        mSurroundViewService->getCameraIds(
+                                [&cameraIds](const hidl_vec<hidl_string>& camIds) {
+                                    cameraIds = camIds;
+                                });
+                        hidl_string cameraId;
+                        if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
+                            const size_t cameraIndex =
+                                    mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                            0, cameraIds.size() - 1);
+                            cameraId = cameraIds[cameraIndex];
+                        } else {
+                            cameraId =
+                                    mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
+                        }
+                        surroundView2dSession->projectCameraPoints(
+                                points2dCamera, cameraId,
+                                []([[maybe_unused]] const hidl_vec<Point2dFloat>& outPoints) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        SvFramesDesc frames;
+                        frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
+                        frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                kMinSvBuffers, kMaxSvBuffers);
+                        frames.svBuffers.resize(numSvBuffers);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            frames.svBuffers[i].viewId =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
+                            frames.svBuffers[i].hardwareBuffer.description[0] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.description[1] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView2dSession->doneWithFrames(frames);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
+                        }
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->stopStream();
+                        mIs2dStreamStarted = false;
+                    }
+                },
+                [&]() {
+                    mSurroundViewService->stop2dSession(
+                            mFuzzedDataProvider.ConsumeBool() ? surroundView2dSession : nullptr);
+                },
+        });
+        surroundView2dFunc();
+    }
+
+    if (surroundView2dSession && mIs2dStreamStarted) {
+        surroundView2dSession->stopStream();
+    }
+}
+
+void SurroundViewFuzzer::invoke3dSessionAPI() {
+    sp<ISurroundView3dSession> surroundView3dSession;
+    while (mFuzzedDataProvider.remaining_bytes() > 0) {
+        auto surroundView3dFunc = mFuzzedDataProvider.PickValueInArray<
+                const std::function<void()>>({
+                [&]() {
+                    mSurroundViewService->start3dSession(
+                            [&surroundView3dSession](const sp<ISurroundView3dSession>& session,
+                                                     SvResult result) {
+                                if (result == SvResult::OK) {
+                                    surroundView3dSession = session;
+                                }
+                            });
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        sp<SurroundViewStream> handler =
+                                sp<SurroundViewStream>::make(surroundView3dSession);
+                        surroundView3dSession->startStream(handler);
+                        mIs3dStreamStarted = true;
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        const size_t numViews =
+                                mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxViews);
+                        std::vector<View3d> views(numViews);
+                        for (size_t i = 0; i < numViews; ++i) {
+                            views[i].viewId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView3dSession->setViews(views);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        Sv3dConfig config;
+                        config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        config.height = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        if (mFuzzedDataProvider.ConsumeBool()) {
+                            config.carDetails = static_cast<SvQuality>(
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
+                        } else {
+                            config.carDetails = mFuzzedDataProvider.ConsumeBool()
+                                                        ? (SvQuality::HIGH)
+                                                        : (SvQuality::LOW);
+                        }
+                        surroundView3dSession->set3dConfig(config);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        surroundView3dSession->get3dConfig([&](Sv3dConfig) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        Point2dInt cameraPoint;
+                        cameraPoint.x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        cameraPoint.y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        std::vector<Point2dInt> cameraPoints = {cameraPoint};
+                        hidl_vec<hidl_string> cameraIds;
+                        mSurroundViewService->getCameraIds(
+                                [&cameraIds](const hidl_vec<hidl_string>& camIds) {
+                                    cameraIds = camIds;
+                                });
+                        hidl_string cameraId;
+                        if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
+                            const size_t cameraIndex =
+                                    mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                            0, cameraIds.size() - 1);
+                            cameraId = cameraIds[cameraIndex];
+                        } else {
+                            cameraId =
+                                    mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
+                        }
+                        std::vector<Point3dFloat> points3d;
+                        surroundView3dSession->projectCameraPointsTo3dSurface(
+                                cameraPoints, cameraId,
+                                [&points3d]([[maybe_unused]] const hidl_vec<Point3dFloat>&
+                                                    points3dproj) { points3d = points3dproj; });
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        // success case
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        initSampleOverlaysData();
+                        // Fail with ID mismatch
+                        // Set id of second overlay in shared memory to 2 (expected is 1).
+                        auto& overlaysDescVector = mOverlaysdata.overlaysMemoryDesc;
+                        auto& pIMemory = mMemory;
+                        int32_t indexPosition = mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
+                                0, mNumOverlays - 1);
+                        int32_t mismatchedValueIndex =
+                                mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
+                                        0, mNumOverlays - 1);
+                        setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, indexPosition,
+                                                 overlaysDescVector[mismatchedValueIndex].id);
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        // Fail with NULL memory
+                        // Set shared memory to null.
+                        mOverlaysdata.overlaysMemory = hidl_memory();
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        SvFramesDesc frames;
+                        frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
+                        frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                kMinSvBuffers, kMaxSvBuffers);
+                        frames.svBuffers.resize(numSvBuffers);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            frames.svBuffers[i].viewId =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
+                            frames.svBuffers[i].hardwareBuffer.description[0] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.description[1] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView3dSession->doneWithFrames(frames);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
+                        }
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        surroundView3dSession->stopStream();
+                        mIs3dStreamStarted = false;
+                    }
+                },
+                [&]() {
+                    mSurroundViewService->stop3dSession(
+                            mFuzzedDataProvider.ConsumeBool() ? surroundView3dSession : nullptr);
+                },
+        });
+        surroundView3dFunc();
+    }
+    if (surroundView3dSession && mIs3dStreamStarted) {
+        surroundView3dSession->stopStream();
+    }
+}
+
+void SurroundViewFuzzer::process() {
+    mFuzzedDataProvider.ConsumeBool() ? invoke2dSessionAPI() : invoke3dSessionAPI();
+}
+
+std::pair<hidl_memory, sp<IMemory>> SurroundViewFuzzer::getMappedSharedMemory(int32_t bytesSize) {
+    const auto nullResult = std::make_pair(hidl_memory(), nullptr);
+
+    sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
+    if (ashmemAllocator.get() == nullptr) {
+        return nullResult;
+    }
+
+    // Allocate shared memory.
+    hidl_memory hidlMemory;
+    bool allocateSuccess = false;
+    Return<void> result =
+            ashmemAllocator->allocate(bytesSize, [&](bool success, const hidl_memory& hidlMem) {
+                if (!success) {
+                    return;
+                }
+                allocateSuccess = success;
+                hidlMemory = hidlMem;
+            });
+
+    // Check result of allocated memory.
+    if (!result.isOk() || !allocateSuccess) {
+        return nullResult;
+    }
+
+    // Map shared memory.
+    sp<IMemory> pIMemory = mapMemory(hidlMemory);
+    if (pIMemory.get() == nullptr) {
+        return nullResult;
+    }
+
+    return std::make_pair(hidlMemory, pIMemory);
+}
+
+void SurroundViewFuzzer::setIndexOfOverlaysMemory(
+        const std::vector<OverlayMemoryDesc>& overlaysMemDesc, sp<IMemory> pIMemory,
+        int32_t indexPosition, uint16_t indexValue) {
+    // Count the number of vertices until the index.
+    int32_t totalVerticesCount = 0;
+    for (int32_t i = 0; i < indexPosition; ++i) {
+        totalVerticesCount += overlaysMemDesc[i].verticesCount;
+    }
+
+    const int32_t indexBytePosition =
+            (indexPosition * kIdByteSize) + (kVertexByteSize * totalVerticesCount);
+
+    uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
+    pSharedMemoryData += indexBytePosition;
+    uint16_t* pIndex16bit = (uint16_t*)pSharedMemoryData;
+
+    // Modify shared memory.
+    pIMemory->update();
+    *pIndex16bit = indexValue;
+    pIMemory->commit();
+}
+
+void SurroundViewFuzzer::initSampleOverlaysData() {
+    const size_t mNumOverlays =
+            mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(kMinOverlays, kMaxOverlays);
+    mOverlaysdata.overlaysMemoryDesc.resize(mNumOverlays);
+
+    int32_t sharedMemBytesSize = 0;
+    std::vector<OverlayMemoryDesc> overlaysDescVector = {};
+    OverlayMemoryDesc overlayMemDesc[mNumOverlays];
+    for (size_t i = 0; i < mNumOverlays; ++i) {
+        overlayMemDesc[i].id = i;
+        overlayMemDesc[i].verticesCount =
+                mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxVertices);
+        overlayMemDesc[i].overlayPrimitive = mFuzzedDataProvider.ConsumeBool()
+                                                     ? (OverlayPrimitive::TRIANGLES)
+                                                     : (OverlayPrimitive::TRIANGLES_STRIP);
+        mOverlaysdata.overlaysMemoryDesc[i] = overlayMemDesc[i];
+
+        sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc[i].verticesCount;
+        overlaysDescVector.push_back(overlayMemDesc[i]);
+    }
+
+    std::pair<hidl_memory, sp<IMemory>> sharedMem = getMappedSharedMemory(sharedMemBytesSize);
+    sp<IMemory> pIMemory = std::get<1>(sharedMem);
+    if (pIMemory.get() == nullptr) {
+        mOverlaysdata = OverlaysData();
+        mMemory = nullptr;
+        return;
+    }
+
+    // Get pointer to shared memory data and set all bytes to 0.
+    uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
+    pIMemory->update();
+    memset(pSharedMemoryData, 0, sharedMemBytesSize);
+    pIMemory->commit();
+
+    // Set indexes in shared memory.
+    for (size_t i = 0; i < mNumOverlays; ++i) {
+        setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, i, overlayMemDesc[i].id);
+    }
+
+    mOverlaysdata.overlaysMemoryDesc = overlaysDescVector;
+    mOverlaysdata.overlaysMemory = std::get<0>(sharedMem);
+    mMemory = pIMemory;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    SurroundViewFuzzer surroundViewFuzzer(data, size);
+    surroundViewFuzzer.process();
+    return 0;
+}
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h
new file mode 100644
index 0000000..23e5a31
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#pragma once
+#include <SurroundViewService.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using ::android::sp;
+using ::android::hidl::memory::V1_0::IMemory;
+
+constexpr size_t kMinOverlays = 2;
+
+class SurroundViewFuzzer {
+  public:
+    SurroundViewFuzzer(const uint8_t* data, size_t size) : mFuzzedDataProvider(data, size) {
+        mSurroundViewService = sp<SurroundViewService>::make();
+    }
+    ~SurroundViewFuzzer() = default;
+    void process();
+
+  private:
+    void invoke2dSessionAPI();
+    void invoke3dSessionAPI();
+    std::pair<hidl_memory, sp<IMemory>> getMappedSharedMemory(int32_t bytesSize);
+    void initSampleOverlaysData();
+    void setIndexOfOverlaysMemory(const std::vector<OverlayMemoryDesc>& overlaysMemDesc,
+                                  sp<IMemory> pIMemory, int32_t indexPosition, uint16_t indexValue);
+    OverlaysData mOverlaysdata = {};
+    size_t mNumOverlays = kMinOverlays;
+    sp<IMemory> mMemory = nullptr;
+    FuzzedDataProvider mFuzzedDataProvider;
+    sp<SurroundViewService> mSurroundViewService = nullptr;
+    bool mIs2dStreamStarted = false;
+    bool mIs3dStreamStarted = false;
+};
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp
new file mode 100644
index 0000000..b81a08c
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SurroundViewStream.h"
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using std::lock_guard;
+
+SurroundViewStream::SurroundViewStream(sp<ISurroundViewSession> pSession)
+    : mSession(pSession), mReceiveFramesCount(0) {}
+
+Return<void> SurroundViewStream::notify(SvEvent svEvent) {
+    lock_guard<mutex> lock(mLock);
+    switch (svEvent) {
+        case SvEvent::STREAM_STARTED:
+        case SvEvent::CONFIG_UPDATED:
+        case SvEvent::STREAM_STOPPED:
+        case SvEvent::FRAME_DROPPED:
+        case SvEvent::TIMEOUT:
+            mReceivedEvents.emplace_back(svEvent);
+            break;
+        default:
+            break;
+    }
+
+    return android::hardware::Void();
+}
+
+Return<void> SurroundViewStream::receiveFrames(const SvFramesDesc& svFramesDesc) {
+    lock_guard<mutex> lock(mLock);
+    if ((mLastReceivedFrames.timestampNs >= svFramesDesc.timestampNs ||
+         mLastReceivedFrames.sequenceId >= svFramesDesc.sequenceId) &&
+        mReceiveFramesCount != 0) {
+        // The incoming frames are with invalid timestamp or sequenceId
+        mAllFramesValid = false;
+    }
+
+    for (int i = 0; i < svFramesDesc.svBuffers.size(); ++i) {
+        if (svFramesDesc.svBuffers[i].hardwareBuffer.nativeHandle == nullptr) {
+            mAllFramesValid = false;
+            // The incoming frames are with invalid nativeHandle
+            break;
+        }
+    }
+
+    ++mReceiveFramesCount;
+
+    // Store all the information except for the handle
+    mLastReceivedFrames.timestampNs = svFramesDesc.timestampNs;
+    mLastReceivedFrames.sequenceId = svFramesDesc.sequenceId;
+    mLastReceivedFrames.svBuffers.resize(svFramesDesc.svBuffers.size());
+    for (int i = 0; i < svFramesDesc.svBuffers.size(); ++i) {
+        mLastReceivedFrames.svBuffers[i].viewId = svFramesDesc.svBuffers[i].viewId;
+        mLastReceivedFrames.svBuffers[i].hardwareBuffer.description =
+                svFramesDesc.svBuffers[i].hardwareBuffer.description;
+    }
+
+    return android::hardware::Void();
+}
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h
new file mode 100644
index 0000000..8135bc1
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/sv/1.0/ISurroundViewSession.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
+#include <android/hardware/automotive/sv/1.0/types.h>
+
+#include <thread>
+#include <vector>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using android::sp;
+using android::hardware::Return;
+using std::mutex;
+using std::vector;
+
+class SurroundViewStream : public ISurroundViewStream {
+  public:
+    SurroundViewStream(sp<ISurroundViewSession> session);
+
+    Return<void> notify(SvEvent svEvent) override;
+    Return<void> receiveFrames(const SvFramesDesc& svFramesDesc) override;
+
+    bool checkEventReceived(SvEvent svEvent);
+    SvFramesDesc getLastReceivedFrames();
+    int getReceiveFramesCount();
+    bool areAllFramesValid();
+    void setDoNotReturnFrames(bool flag);
+
+  private:
+    mutex mLock;
+
+    vector<SvEvent> mReceivedEvents;
+    sp<ISurroundViewSession> mSession;
+    SvFramesDesc mLastReceivedFrames;
+    int mReceiveFramesCount;
+    bool mAllFramesValid = true;
+};
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/bluetooth/1.0/default/test/fuzzer/Android.bp b/bluetooth/1.0/default/test/fuzzer/Android.bp
index 81f328e..691136f 100644
--- a/bluetooth/1.0/default/test/fuzzer/Android.bp
+++ b/bluetooth/1.0/default/test/fuzzer/Android.bp
@@ -46,7 +46,6 @@
         "android.hardware.bluetooth-async",
         "android.hardware.bluetooth-hci",
         "libcutils",
-        "libutils",
     ],
     shared_libs: [
         "android.hardware.bluetooth@1.0",
@@ -54,6 +53,7 @@
         "libhidlbase",
         "libbt-vendor-fuzz",
         "liblog",
+        "libutils",
     ],
     fuzz_config: {
         cc: [
diff --git a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
index 90cdc66..fb8df99 100644
--- a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
+++ b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
@@ -88,11 +88,18 @@
     }
     mBtHci->close();
     mBtHci.clear();
+    for (size_t i = 0; i < mFdCount; ++i) {
+      if (mFdList[i]) {
+        close(mFdList[i]);
+      }
+    }
   }
   bool init(const uint8_t* data, size_t size);
   void process();
 
  private:
+  size_t mFdCount = 1;
+  int32_t mFdList[CH_MAX] = {0};
   sp<BluetoothHci> mBtHci = nullptr;
   FuzzedDataProvider* mFdp = nullptr;
 };
@@ -143,17 +150,15 @@
   bool shouldSetH4Protocol = mFdp->ConsumeBool();
   BtVendor* btVendor = BtVendor::getInstance();
 
-  size_t fdcount = 1;
-  int32_t fdList[CH_MAX] = {0};
   if (!shouldSetH4Protocol) {
-    fdcount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
+    mFdCount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
   }
 
-  for (size_t i = 0; i < fdcount; ++i) {
-    fdList[i] = open("/dev/null", O_RDWR | O_CREAT);
+  for (size_t i = 0; i < mFdCount; ++i) {
+    mFdList[i] = open("/dev/null", O_RDWR | O_CREAT);
   }
 
-  btVendor->populateFdList(fdList, fdcount);
+  btVendor->populateFdList(mFdList, mFdCount);
   mBtHci->initialize(bluetoothCallback);
 
   if (!bluetoothCallback->isInitialized) {
@@ -181,12 +186,6 @@
   }
 
   btVendor->callRemainingCbacks();
-
-  for (size_t i = 0; i < fdcount; ++i) {
-    if (fdList[i]) {
-      close(fdList[i]);
-    }
-  }
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index baec9c2..33a3187 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -44,4 +44,6 @@
   LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
   LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH = 8,
   LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 9,
+  A2DP_SOFTWARE_DECODING_DATAPATH = 10,
+  A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH = 11,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index 95beee7..7acb5c6 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -62,4 +62,12 @@
      * Audio broadcast channels. This is a control path only.
      */
     LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+    /**
+     * A2DP legacy that AVDTP media is decoded by Bluetooth Stack
+     */
+    A2DP_SOFTWARE_DECODING_DATAPATH,
+    /**
+     * The decoding of AVDTP media is done by HW and there is control only
+     */
+    A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
 }
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index 4b4713d..2d0d8c9 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -28,10 +28,18 @@
 namespace bluetooth {
 namespace audio {
 
-A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() {
+A2dpOffloadEncodingAudioProvider::A2dpOffloadEncodingAudioProvider()
+    : A2dpOffloadAudioProvider() {
   session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
 }
 
+A2dpOffloadDecodingAudioProvider::A2dpOffloadDecodingAudioProvider()
+    : A2dpOffloadAudioProvider() {
+  session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH;
+}
+
+A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() {}
+
 bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) {
   return (session_type == session_type_);
 }
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
index 4621e85..e6f188b 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -40,6 +40,16 @@
   ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
 };
 
+class A2dpOffloadEncodingAudioProvider : public A2dpOffloadAudioProvider {
+ public:
+  A2dpOffloadEncodingAudioProvider();
+};
+
+class A2dpOffloadDecodingAudioProvider : public A2dpOffloadAudioProvider {
+ public:
+  A2dpOffloadDecodingAudioProvider();
+};
+
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace hardware
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
index 59df3a9..bd2da95 100644
--- a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
@@ -40,6 +40,16 @@
 static constexpr uint32_t kBufferCount = 2;  // double buffer
 static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
 
+A2dpSoftwareEncodingAudioProvider::A2dpSoftwareEncodingAudioProvider()
+    : A2dpSoftwareAudioProvider() {
+  session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
+}
+
+A2dpSoftwareDecodingAudioProvider::A2dpSoftwareDecodingAudioProvider()
+    : A2dpSoftwareAudioProvider() {
+  session_type_ = SessionType::A2DP_SOFTWARE_DECODING_DATAPATH;
+}
+
 A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider()
     : BluetoothAudioProvider(), data_mq_(nullptr) {
   LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
@@ -48,7 +58,6 @@
       new DataMQ(kDataMqSize, /* EventFlag */ true));
   if (data_mq && data_mq->isValid()) {
     data_mq_ = std::move(data_mq);
-    session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
   } else {
     ALOGE_IF(!data_mq, "failed to allocate data MQ");
     ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid");
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
index 10f533a..3ebecf2 100644
--- a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
@@ -43,6 +43,16 @@
   ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
 };
 
+class A2dpSoftwareEncodingAudioProvider : public A2dpSoftwareAudioProvider {
+ public:
+  A2dpSoftwareEncodingAudioProvider();
+};
+
+class A2dpSoftwareDecodingAudioProvider : public A2dpSoftwareAudioProvider {
+ public:
+  A2dpSoftwareDecodingAudioProvider();
+};
+
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace hardware
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 0dd8148..2a88959 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -45,6 +45,7 @@
   latency_modes_ = latencyModes;
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
   stack_iface_ = host_if;
+  is_binder_died = false;
 
   AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
                        this);
@@ -59,8 +60,10 @@
   if (stack_iface_ != nullptr) {
     BluetoothAudioSessionReport::OnSessionEnded(session_type_);
 
-    AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
-                           death_recipient_.get(), this);
+    if (!is_binder_died) {
+      AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
+                             death_recipient_.get(), this);
+    }
   } else {
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << " has NO session";
@@ -147,6 +150,7 @@
     LOG(ERROR) << __func__ << ": Null AudioProvider HAL died";
     return;
   }
+  provider->is_binder_died = true;
   provider->endSession();
 }
 
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index a9f830a..dbfff7d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -62,6 +62,7 @@
   std::unique_ptr<AudioConfiguration> audio_config_ = nullptr;
   SessionType session_type_;
   std::vector<LatencyMode> latency_modes_;
+  bool is_binder_died = false;
 };
 
 }  // namespace audio
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 1e1680a..91731d4 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -44,10 +44,10 @@
 
   switch (session_type) {
     case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
-      provider = ndk::SharedRefBase::make<A2dpSoftwareAudioProvider>();
+      provider = ndk::SharedRefBase::make<A2dpSoftwareEncodingAudioProvider>();
       break;
     case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
-      provider = ndk::SharedRefBase::make<A2dpOffloadAudioProvider>();
+      provider = ndk::SharedRefBase::make<A2dpOffloadEncodingAudioProvider>();
       break;
     case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
       provider = ndk::SharedRefBase::make<HearingAidAudioProvider>();
@@ -72,6 +72,12 @@
       provider =
           ndk::SharedRefBase::make<LeAudioOffloadBroadcastAudioProvider>();
       break;
+    case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<A2dpSoftwareDecodingAudioProvider>();
+      break;
+    case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>();
+      break;
     default:
       provider = nullptr;
       break;
@@ -90,7 +96,8 @@
 ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities(
     const SessionType session_type,
     std::vector<AudioCapabilities>* _aidl_return) {
-  if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+  if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+      session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     auto codec_capabilities =
         BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type);
     _aidl_return->resize(codec_capabilities.size());
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
index 911c928..c16ff54 100644
--- a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
@@ -91,17 +91,21 @@
   else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH)
     buffer_modifier = kBufferInCount;
 
+  // 24 bit audio stream is sent as unpacked
+  int bytes_per_sample =
+      (pcm_config.bitsPerSample == 24) ? 4 : (pcm_config.bitsPerSample / 8);
+
   uint32_t data_mq_size =
       (ceil(pcm_config.sampleRateHz) / 1000) *
-      channel_mode_to_channel_count(pcm_config.channelMode) *
-      (pcm_config.bitsPerSample / 8) * (pcm_config.dataIntervalUs / 1000) *
-      buffer_modifier;
+      channel_mode_to_channel_count(pcm_config.channelMode) * bytes_per_sample *
+      (pcm_config.dataIntervalUs / 1000) * buffer_modifier;
   if (data_mq_size <= 0) {
     LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size
                << ", SampleRateHz: " << pcm_config.sampleRateHz
                << ", ChannelMode: " << toString(pcm_config.channelMode)
                << ", BitsPerSample: "
                << static_cast<int>(pcm_config.bitsPerSample)
+               << ", BytesPerSample: " << bytes_per_sample
                << ", DataIntervalUs: " << pcm_config.dataIntervalUs
                << ", SessionType: " << toString(session_type_);
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 18352a0..b599365 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -201,7 +201,8 @@
         ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
                   AudioCapabilities::pcmCapabilities);
       } break;
-      case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
+      case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
         std::unordered_set<CodecType> codec_types;
         // empty capability means offload is unsupported
         for (auto& audio_capability : temp_provider_capabilities_) {
@@ -250,6 +251,16 @@
                     AudioCapabilities::leAudioCapabilities);
         }
       } break;
+      case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
+        if (!temp_provider_capabilities_.empty()) {
+          ASSERT_EQ(temp_provider_capabilities_.size(), 1);
+          ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
+                    AudioCapabilities::pcmCapabilities);
+        }
+      } break;
+      default: {
+        ASSERT_TRUE(temp_provider_capabilities_.empty());
+      }
     }
   }
 
@@ -266,7 +277,7 @@
       ASSERT_NE(audio_provider_, nullptr);
       audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
     } else {
-      // Hardware offloading is optional
+      // optional session type
       ASSERT_TRUE(
           session_type == SessionType::UNKNOWN ||
           session_type ==
@@ -277,147 +288,14 @@
               SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
           session_type ==
               SessionType::
-                  LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+                  LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+          session_type ==
+              SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+          session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
       ASSERT_EQ(audio_provider_, nullptr);
     }
   }
 
-  bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
-    if (temp_provider_capabilities_.size() != 1 ||
-        temp_provider_capabilities_[0].getTag() !=
-            AudioCapabilities::pcmCapabilities) {
-      return false;
-    }
-    auto pcm_capability = temp_provider_capabilities_[0]
-                              .get<AudioCapabilities::pcmCapabilities>();
-    return (contained_in_vector(pcm_capability.channelMode,
-                                pcm_config.channelMode) &&
-            contained_in_vector(pcm_capability.sampleRateHz,
-                                pcm_config.sampleRateHz) &&
-            contained_in_vector(pcm_capability.bitsPerSample,
-                                pcm_config.bitsPerSample));
-  }
-
-  std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
-  std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
-  std::shared_ptr<IBluetoothAudioPort> audio_port_;
-  std::vector<AudioCapabilities> temp_provider_capabilities_;
-
-  static constexpr SessionType kSessionTypes[] = {
-      SessionType::UNKNOWN,
-      SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
-      SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
-      SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
-      SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
-      SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
-      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
-      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
-      SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
-      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
-  };
-};
-
-/**
- * Test whether we can get the FactoryService from HIDL
- */
-TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
-
-/**
- * Test whether we can open a provider for each provider returned by
- * getProviderCapabilities() with non-empty capabalities
- */
-TEST_P(BluetoothAudioProviderFactoryAidl,
-       OpenProviderAndCheckCapabilitiesBySession) {
-  for (auto session_type : kSessionTypes) {
-    GetProviderCapabilitiesHelper(session_type);
-    OpenProviderHelper(session_type);
-    // We must be able to open a provider if its getProviderCapabilities()
-    // returns non-empty list.
-    EXPECT_TRUE(temp_provider_capabilities_.empty() ||
-                audio_provider_ != nullptr);
-  }
-}
-
-/**
- * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
- */
-class BluetoothAudioProviderA2dpSoftwareAidl
-    : public BluetoothAudioProviderFactoryAidl {
- public:
-  virtual void SetUp() override {
-    BluetoothAudioProviderFactoryAidl::SetUp();
-    GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
-    OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
-    ASSERT_NE(audio_provider_, nullptr);
-  }
-
-  virtual void TearDown() override {
-    audio_port_ = nullptr;
-    audio_provider_ = nullptr;
-    BluetoothAudioProviderFactoryAidl::TearDown();
-  }
-};
-
-/**
- * Test whether we can open a provider of type
- */
-TEST_P(BluetoothAudioProviderA2dpSoftwareAidl, OpenA2dpSoftwareProvider) {}
-
-/**
- * Test whether each provider of type
- * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
- * different PCM config
- */
-TEST_P(BluetoothAudioProviderA2dpSoftwareAidl,
-       StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
-  for (auto sample_rate : a2dp_sample_rates) {
-    for (auto bits_per_sample : a2dp_bits_per_samples) {
-      for (auto channel_mode : a2dp_channel_modes) {
-        PcmConfiguration pcm_config{
-            .sampleRateHz = sample_rate,
-            .bitsPerSample = bits_per_sample,
-            .channelMode = channel_mode,
-        };
-        bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
-        DataMQDesc mq_desc;
-        auto aidl_retval = audio_provider_->startSession(
-            audio_port_, AudioConfiguration(pcm_config), latency_modes,
-            &mq_desc);
-        DataMQ data_mq(mq_desc);
-
-        EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
-        if (is_codec_config_valid) {
-          EXPECT_TRUE(data_mq.isValid());
-        }
-        EXPECT_TRUE(audio_provider_->endSession().isOk());
-      }
-    }
-  }
-}
-
-/**
- * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
- */
-class BluetoothAudioProviderA2dpHardwareAidl
-    : public BluetoothAudioProviderFactoryAidl {
- public:
-  virtual void SetUp() override {
-    BluetoothAudioProviderFactoryAidl::SetUp();
-    GetProviderCapabilitiesHelper(
-        SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
-    OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
-    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
-                audio_provider_ != nullptr);
-  }
-
-  virtual void TearDown() override {
-    audio_port_ = nullptr;
-    audio_provider_ = nullptr;
-    BluetoothAudioProviderFactoryAidl::TearDown();
-  }
-
-  bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
-
   void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
     temp_codec_capabilities_ = nullptr;
     for (auto& codec_capability : temp_provider_capabilities_) {
@@ -641,23 +519,163 @@
     return lc3_codec_specifics;
   }
 
+  bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
+    if (temp_provider_capabilities_.size() != 1 ||
+        temp_provider_capabilities_[0].getTag() !=
+            AudioCapabilities::pcmCapabilities) {
+      return false;
+    }
+    auto pcm_capability = temp_provider_capabilities_[0]
+                              .get<AudioCapabilities::pcmCapabilities>();
+    return (contained_in_vector(pcm_capability.channelMode,
+                                pcm_config.channelMode) &&
+            contained_in_vector(pcm_capability.sampleRateHz,
+                                pcm_config.sampleRateHz) &&
+            contained_in_vector(pcm_capability.bitsPerSample,
+                                pcm_config.bitsPerSample));
+  }
+
+  std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
+  std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
+  std::shared_ptr<IBluetoothAudioPort> audio_port_;
+  std::vector<AudioCapabilities> temp_provider_capabilities_;
+
   // temp storage saves the specified codec capability by
   // GetOffloadCodecCapabilityHelper()
   CodecCapabilities* temp_codec_capabilities_;
+
+  static constexpr SessionType kSessionTypes[] = {
+      SessionType::UNKNOWN,
+      SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+      SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+      SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+      SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+      SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+  };
+};
+
+/**
+ * Test whether we can get the FactoryService from HIDL
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
+
+/**
+ * Test whether we can open a provider for each provider returned by
+ * getProviderCapabilities() with non-empty capabalities
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl,
+       OpenProviderAndCheckCapabilitiesBySession) {
+  for (auto session_type : kSessionTypes) {
+    GetProviderCapabilitiesHelper(session_type);
+    OpenProviderHelper(session_type);
+    // We must be able to open a provider if its getProviderCapabilities()
+    // returns non-empty list.
+    EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+}
+
+/**
+ * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpEncodingSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
 };
 
 /**
  * Test whether we can open a provider of type
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl, OpenA2dpHardwareProvider) {}
+TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
+       OpenA2dpEncodingSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
+       StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : a2dp_sample_rates) {
+    for (auto bits_per_sample : a2dp_bits_per_samples) {
+      for (auto channel_mode : a2dp_channel_modes) {
+        PcmConfiguration pcm_config{
+            .sampleRateHz = sample_rate,
+            .bitsPerSample = bits_per_sample,
+            .channelMode = channel_mode,
+        };
+        bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+        DataMQDesc mq_desc;
+        auto aidl_retval = audio_provider_->startSession(
+            audio_port_, AudioConfiguration(pcm_config), latency_modes,
+            &mq_desc);
+        DataMQ data_mq(mq_desc);
+
+        EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+        if (is_codec_config_valid) {
+          EXPECT_TRUE(data_mq.isValid());
+        }
+        EXPECT_TRUE(audio_provider_->endSession().isOk());
+      }
+    }
+  }
+}
+
+/**
+ * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpEncodingHardwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       OpenA2dpEncodingHardwareProvider) {}
 
 /**
  * Test whether each provider of type
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * SBC hardware encoding config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpSbcHardwareSession) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpSbcEncodingHardwareSession) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -686,8 +704,8 @@
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * AAC hardware encoding config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpAacHardwareSession) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpAacEncodingHardwareSession) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -716,8 +734,8 @@
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * LDAC hardware encoding config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpLdacHardwareSession) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpLdacEncodingHardwareSession) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -746,8 +764,8 @@
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * LDAC hardware encoding config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpLc3HardwareSession) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpLc3EncodingHardwareSession) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -776,8 +794,8 @@
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * AptX hardware encoding config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpAptxHardwareSession) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpAptxEncodingHardwareSession) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -812,8 +830,8 @@
  * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
  * an invalid codec config
  */
-TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
-       StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
+TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
+       StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
   if (!IsOffloadSupported()) {
     return;
   }
@@ -1588,6 +1606,314 @@
   }
 }
 
+/**
+ * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpDecodingSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
+       OpenA2dpDecodingSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
+       StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : a2dp_sample_rates) {
+    for (auto bits_per_sample : a2dp_bits_per_samples) {
+      for (auto channel_mode : a2dp_channel_modes) {
+        PcmConfiguration pcm_config{
+            .sampleRateHz = sample_rate,
+            .bitsPerSample = bits_per_sample,
+            .channelMode = channel_mode,
+        };
+        bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+        DataMQDesc mq_desc;
+        auto aidl_retval = audio_provider_->startSession(
+            audio_port_, AudioConfiguration(pcm_config), latency_modes,
+            &mq_desc);
+        DataMQ data_mq(mq_desc);
+
+        EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+        if (is_codec_config_valid) {
+          EXPECT_TRUE(data_mq.isValid());
+        }
+        EXPECT_TRUE(audio_provider_->endSession().isOk());
+      }
+    }
+  }
+}
+
+/**
+ * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpDecodingHardwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       OpenA2dpDecodingHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * SBC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpSbcDecodingHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::SBC,
+      .encodedAudioBitrate = 328000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : sbc_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * AAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpAacDecodingHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::AAC,
+      .encodedAudioBitrate = 320000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : aac_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpLdacDecodingHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::LDAC,
+      .encodedAudioBitrate = 990000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : ldac_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpLc3DecodingHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::LC3,
+      .encodedAudioBitrate = 990000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto lc3_codec_specifics = GetLc3CodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : lc3_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * AptX hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpAptxDecodingHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
+    CodecConfiguration codec_config = {
+        .codecType = codec_type,
+        .encodedAudioBitrate =
+            (codec_type == CodecType::APTX ? 352000 : 576000),
+        .peerMtu = 1005,
+        .isScmstEnabled = false,
+    };
+
+    auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
+        (codec_type == CodecType::APTX_HD ? true : false), true);
+
+    for (auto& codec_specific : aptx_codec_specifics) {
+      copy_codec_specific(codec_config.config, codec_specific);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(codec_config), latency_modes,
+          &mq_desc);
+
+      ASSERT_TRUE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
+ * an invalid codec config
+ */
+TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
+       StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+  ASSERT_NE(audio_provider_, nullptr);
+
+  std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
+  for (auto codec_type : a2dp_codec_types) {
+    switch (codec_type) {
+      case CodecType::SBC:
+        codec_specifics = GetSbcCodecSpecificSupportedList(false);
+        break;
+      case CodecType::AAC:
+        codec_specifics = GetAacCodecSpecificSupportedList(false);
+        break;
+      case CodecType::LDAC:
+        codec_specifics = GetLdacCodecSpecificSupportedList(false);
+        break;
+      case CodecType::APTX:
+        codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
+        break;
+      case CodecType::APTX_HD:
+        codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
+        break;
+      case CodecType::LC3:
+        codec_specifics = GetLc3CodecSpecificSupportedList(false);
+        continue;
+      case CodecType::APTX_ADAPTIVE:
+      case CodecType::VENDOR:
+      case CodecType::UNKNOWN:
+        codec_specifics.clear();
+        break;
+    }
+    if (codec_specifics.empty()) {
+      continue;
+    }
+
+    CodecConfiguration codec_config = {
+        .codecType = codec_type,
+        .encodedAudioBitrate = 328000,
+        .peerMtu = 1005,
+        .isScmstEnabled = false,
+    };
+    for (auto codec_specific : codec_specifics) {
+      copy_codec_specific(codec_config.config, codec_specific);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(codec_config), latency_modes,
+          &mq_desc);
+
+      // AIDL call should fail on invalid codec
+      ASSERT_FALSE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
     BluetoothAudioProviderFactoryAidl);
 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
@@ -1596,15 +1922,17 @@
                          android::PrintInstanceNameToString);
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
-    BluetoothAudioProviderA2dpSoftwareAidl);
-INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpSoftwareAidl,
+    BluetoothAudioProviderA2dpEncodingSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderA2dpEncodingSoftwareAidl,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              IBluetoothAudioProviderFactory::descriptor)),
                          android::PrintInstanceNameToString);
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
-    BluetoothAudioProviderA2dpHardwareAidl);
-INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpHardwareAidl,
+    BluetoothAudioProviderA2dpEncodingHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderA2dpEncodingHardwareAidl,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              IBluetoothAudioProviderFactory::descriptor)),
                          android::PrintInstanceNameToString);
@@ -1665,6 +1993,22 @@
                              IBluetoothAudioProviderFactory::descriptor)),
                          android::PrintInstanceNameToString);
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderA2dpDecodingSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderA2dpDecodingSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderA2dpDecodingHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderA2dpDecodingHardwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
   ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index 8fd1ab5..1fb0e41 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -37,7 +37,7 @@
 namespace audio {
 
 static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
-    .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000},
+    .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
     .bitsPerSample = {16, 24, 32},
     .dataIntervalUs = {},
@@ -115,6 +115,20 @@
     .octetsPerFrame = {40}};
 
 // Default Supported Codecs
+// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60
+static const Lc3Capabilities kLc3Capability_24_2 = {
+    .samplingFrequencyHz = {24000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {60}};
+
+// Default Supported Codecs
+// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80
+static const Lc3Capabilities kLc3Capability_32_2 = {
+    .samplingFrequencyHz = {32000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {80}};
+
+// Default Supported Codecs
 // LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
 static const Lc3Capabilities kLc3Capability_48_4 = {
     .samplingFrequencyHz = {48000},
@@ -122,7 +136,8 @@
     .octetsPerFrame = {120}};
 
 static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
-    kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
+    kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2,
+    kLc3Capability_16_2, kLc3Capability_16_1};
 
 static AudioLocation stereoAudio = static_cast<AudioLocation>(
     static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
@@ -323,7 +338,8 @@
 std::vector<CodecCapabilities>
 BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
     const SessionType& session_type) {
-  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     return {};
   }
   std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
@@ -389,7 +405,8 @@
 
 bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
     const SessionType& session_type, const CodecConfiguration& codec_config) {
-  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     LOG(ERROR) << __func__
                << ": Invalid SessionType=" << toString(session_type);
     return false;
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index cdee520..3214bf2 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -92,6 +92,7 @@
   if (!IsSessionReady()) {
     switch (session_type_) {
       case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
         return AudioConfiguration(CodecConfiguration{});
       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
@@ -143,6 +144,7 @@
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
        session_type_ ==
            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
        (data_mq_ != nullptr && data_mq_->isValid()));
   return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
 }
@@ -267,9 +269,11 @@
        session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
        session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
        session_type_ ==
-           SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
+           SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
   bool is_offload_a2dp_session =
-      (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+      (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
   bool is_offload_le_audio_session =
       (session_type_ ==
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
@@ -468,7 +472,9 @@
   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
             << track_count << " track(s)";
   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
-      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     return;
   }
 
@@ -509,7 +515,9 @@
   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
             << track_count << " track(s)";
   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
-      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     return;
   }
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index 5b838b0..0782c82 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -82,6 +82,7 @@
     }
     switch (session_type) {
       case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
         return AudioConfiguration(CodecConfiguration{});
       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 193fd2b..524242f 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -74,6 +74,18 @@
 }
 
 vintf_compatibility_matrix {
+    name: "framework_compatibility_matrix.7.xml",
+    stem: "compatibility_matrix.7.xml",
+    srcs: [
+        "compatibility_matrix.7.xml",
+    ],
+    kernel_configs: [
+        "kernel_config_t_5.10",
+        "kernel_config_t_5.15",
+    ],
+}
+
+vintf_compatibility_matrix {
     name: "framework_compatibility_matrix.current.xml",
     stem: "compatibility_matrix.current.xml",
     srcs: [
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 9e715bf..d19f0da 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -102,6 +102,7 @@
     framework_compatibility_matrix.4.xml \
     framework_compatibility_matrix.5.xml \
     framework_compatibility_matrix.6.xml \
+    framework_compatibility_matrix.7.xml \
     framework_compatibility_matrix.current.xml \
     framework_compatibility_matrix.device.xml \
 
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
new file mode 100644
index 0000000..6967671
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -0,0 +1,720 @@
+<compatibility-matrix version="1.0" type="framework" level="7">
+    <hal format="hidl" optional="true">
+        <name>android.hardware.atrace</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAtraceDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio</name>
+        <version>6.0</version>
+        <version>7.0-1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio.effect</name>
+        <version>6.0</version>
+        <version>7.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.authsecret</name>
+         <version>1</version>
+         <interface>
+             <name>IAuthSecret</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.authsecret</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAuthSecret</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.can</name>
+        <version>1.0</version>
+        <interface>
+            <name>ICanBus</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+        <interface>
+            <name>ICanController</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <instance>default</instance>
+            <regex-instance>[a-z]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <interface>
+            <name>IOccupantAwareness</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.sv</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISurroundViewService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBiometricsFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <interface>
+            <name>IFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>2.1-3</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <interface>
+            <name>IFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <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>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBroadcastRadioFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>2.0</version>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.camera.provider</name>
+        <version>2.4-7</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <regex-instance>[^/]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.cas</name>
+        <version>1.1-2</version>
+        <interface>
+            <name>IMediaCasService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1.0</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>1.2</version>
+        <interface>
+            <name>IContexthub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.drm</name>
+        <version>1.3-4</version>
+        <interface>
+            <name>ICryptoFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.gatekeeper</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>2.0-1</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.allocator</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.0</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.composer</name>
+        <version>2.1-4</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.mapper</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.1</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="false">
+        <name>android.hardware.health</name>
+        <version>1</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health.storage</name>
+        <version>1</version>
+        <interface>
+            <name>IStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.identity</name>
+        <version>1-4</version>
+        <interface>
+            <name>IIdentityCredentialStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <interface>
+            <name>IConsumerIr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.input.classifier</name>
+        <version>1.0</version>
+        <interface>
+            <name>IInputClassifier</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.keymaster</name>
+        <version>3.0</version>
+        <version>4.0-1</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.keymaster</name>
+        <version>4.0-1</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.dice</name>
+        <version>1</version>
+        <interface>
+            <name>IDiceDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
+        <interface>
+            <name>IKeyMintDevice</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
+        <interface>
+            <name>IRemotelyProvisionedComponent</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>1</version>
+        <interface>
+            <name>ILights</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.c2</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IComponentStore</name>
+            <regex-instance>default[0-9]*</regex-instance>
+            <regex-instance>vendor[0-9]*_software</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.omx</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1-4</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <version>1.2</version>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="false">
+        <name>android.hardware.power</name>
+        <version>1-2</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power.stats</name>
+        <interface>
+            <name>IPowerStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.data</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioData</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.messaging</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioMessaging</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.modem</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioModem</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.network</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioNetwork</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sim</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioSim</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.voice</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioVoice</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio</name>
+        <version>1.2</version>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.rebootescrow</name>
+        <version>1</version>
+        <interface>
+            <name>IRebootEscrow</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.secure_element</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>ISecureElement</name>
+            <regex-instance>eSE[1-9][0-9]*</regex-instance>
+            <regex-instance>SIM[1-9][0-9]*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.secureclock</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureClock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.sharedsecret</name>
+        <version>1</version>
+        <interface>
+            <name>ISharedSecret</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>1.0</version>
+        <version>2.0-1</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.3</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOffloadConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.control</name>
+        <version>1.1</version>
+        <interface>
+            <name>IOffloadControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.thermal</name>
+        <version>2.0</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.cec</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1.0</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>1.0</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>1</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1.3-5</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>1.2-4</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6967671..2979b11 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -1,4 +1,4 @@
-<compatibility-matrix version="1.0" type="framework" level="7">
+<compatibility-matrix version="1.0" type="framework" level="8">
     <hal format="hidl" optional="true">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
@@ -638,6 +638,13 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb</name>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.usb.gadget</name>
         <version>1.0-2</version>
diff --git a/confirmationui/support/Android.bp b/confirmationui/support/Android.bp
index 6ab83f2..1200115 100644
--- a/confirmationui/support/Android.bp
+++ b/confirmationui/support/Android.bp
@@ -36,7 +36,7 @@
     ],
     export_include_dirs: [
         "include",
-    ]
+    ],
 }
 
 cc_test {
@@ -56,6 +56,5 @@
         "libhidlbase",
     ],
     test_suites: ["general-tests"],
-    clang: true,
-    cflags: [ "-O0" ],
+    cflags: ["-O0"],
 }
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 0171dd6..3527cca 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2on1adapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
index 3965d12..d613ba9 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2onfbadapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Wextra",
@@ -37,6 +36,9 @@
     ],
 
     header_libs: ["libhardware_headers"],
-    shared_libs: ["liblog", "libsync"],
+    shared_libs: [
+        "liblog",
+        "libsync",
+    ],
     export_include_dirs: ["include"],
 }
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index cd06415..fcad499 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -1,2 +1,4 @@
 # Bug component: 30545
 elsk@google.com
+smoreland@google.com
+stayfan@google.com
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8eab997..0d426da 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -159,3 +159,70 @@
     init_rc: ["android.hardware.health-service.example_recovery.rc"],
     overrides: ["charger.recovery"],
 }
+
+// AIDL Fuzz version of libhealth2impl.
+cc_library_static {
+    name: "fuzz_libhealth_aidl_impl",
+    defaults: [
+        "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
+    ],
+    recovery_available: true,
+    export_include_dirs: ["include"],
+    export_static_lib_headers: [
+        "libbatterymonitor",
+    ],
+    srcs: [
+        "ChargerUtils.cpp",
+        "health-convert.cpp",
+        "HalHealthLoop.cpp",
+        "Health.cpp",
+        "LinkedCallback.cpp",
+    ],
+    target: {
+        recovery: {
+            exclude_srcs: [
+                "ChargerUtils.cpp",
+            ],
+        },
+    },
+}
+
+cc_fuzz {
+    name: "android.hardware.health-service.aidl_fuzzer",
+    defaults: [
+        "libhealth_aidl_impl_user",
+    ],
+    static_libs: [
+        "android.hardware.health-V1-ndk",
+        "libbase",
+        "libbinder_random_parcel",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "fuzz_libhealth_aidl_impl",
+    ],
+    target: {
+        android: {
+            shared_libs: [
+                "libbinder_ndk",
+                "libbinder",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libbinder_ndk",
+                "libbinder",
+            ],
+        },
+        darwin: {
+            enabled: false,
+        },
+    },
+    srcs: ["fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "hamzeh@google.com",
+        ],
+    },
+}
diff --git a/health/aidl/default/fuzzer.cpp b/health/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..b7c6d39
--- /dev/null
+++ b/health/aidl/default/fuzzer.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <health-impl/Health.h>
+#include <health/utils.h>
+
+using aidl::android::hardware::health::Health;
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+
+    fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
\ No newline at end of file
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 20faeee..942e4d7 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -57,6 +57,7 @@
         "general-tests",
         "vts",
     ],
+    require_root: true,
 }
 
 java_test_host {
diff --git a/keymaster/4.0/support/fuzzer/Android.bp b/keymaster/4.0/support/fuzzer/Android.bp
index 3a3f4d5..8bc681a 100644
--- a/keymaster/4.0/support/fuzzer/Android.bp
+++ b/keymaster/4.0/support/fuzzer/Android.bp
@@ -30,12 +30,12 @@
         "libbase",
         "liblog",
         "libkeymaster4support",
-        "libutils",
     ],
     shared_libs: [
         "android.hardware.keymaster@4.0",
         "libcrypto",
         "libhidlbase",
+        "libutils",
     ],
     fuzz_config: {
         cc: [
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 14c756d..dd6b0f7 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2866,8 +2866,8 @@
 
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
         string plaintext;
-        ErrorCode error = Finish(message, &plaintext);
-        if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+        ErrorCode error = Finish(ciphertext, &plaintext);
+        if (error == ErrorCode::INVALID_ARGUMENT) {
             // This is the expected error, we can exit the test now.
             return;
         } else {
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
index d9a6363..5fa13e7 100644
--- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -24,6 +24,7 @@
 #include <android-base/strings.h>
 #include <android/api-level.h>
 
+#include <VtsCoreUtil.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -377,6 +378,10 @@
     return android::base::GetIntProperty("ro.product.first_api_level", __ANDROID_API_T__);
 }
 
+static bool isTV() {
+    return testing::deviceSupportsFeature("android.software.leanback");
+}
+
 // list components and roles.
 TEST_P(StoreHidlTest, OmxCodecAllowedTest) {
     hidl_vec<IOmx::ComponentInfo> componentInfos = getComponentInfoList(omx);
@@ -384,9 +389,16 @@
         for (std::string role : info.mRoles) {
             if (role.find("video_decoder") != std::string::npos ||
                 role.find("video_encoder") != std::string::npos) {
-                ASSERT_LT(getFirstApiLevel(), __ANDROID_API_S__)
-                        << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
-                        << " not allowed for devices launching with Android S and above";
+                // Codec2 is not mandatory on Android TV devices that launched with Android S
+                if (isTV()) {
+                    ASSERT_LT(getFirstApiLevel(), __ANDROID_API_T__)
+                            << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
+                            << " not allowed for devices launching with Android T and above";
+                } else {
+                    ASSERT_LT(getFirstApiLevel(), __ANDROID_API_S__)
+                            << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
+                            << " not allowed for devices launching with Android S and above";
+                }
             }
             if (role.find("audio_decoder") != std::string::npos ||
                 role.find("audio_encoder") != std::string::npos) {
diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp
index daa10fd..d98fef0 100644
--- a/neuralnetworks/1.0/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.0/utils/src/Conversions.cpp
@@ -110,8 +110,9 @@
             return NN_ERROR() << "Unable to convert invalid ashmem memory object with "
                               << memory.handle()->numInts << " numInts, but expected 0";
         }
+        auto fd = NN_TRY(nn::dupFd(memory.handle()->data[0]));
         auto handle = nn::Memory::Ashmem{
-                .fd = NN_TRY(nn::dupFd(memory.handle()->data[0])),
+                .fd = std::move(fd),
                 .size = static_cast<size_t>(memory.size()),
         };
         return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(handle)});
@@ -137,12 +138,13 @@
     }
 
     if (memory.name() != "hardware_buffer_blob") {
-        auto handle = nn::Memory::Unknown{
-                .handle = NN_TRY(unknownHandleFromNativeHandle(memory.handle())),
+        auto handle = NN_TRY(unknownHandleFromNativeHandle(memory.handle()));
+        auto unknown = nn::Memory::Unknown{
+                .handle = std::move(handle),
                 .size = static_cast<size_t>(memory.size()),
                 .name = memory.name(),
         };
-        return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(handle)});
+        return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(unknown)});
     }
 
 #ifdef __ANDROID__
@@ -245,19 +247,23 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_0::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
+            .lifetime = lifetime,
+            .location = location,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_0::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -298,26 +304,30 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
     };
 }
 
 GeneralResult<Request::Argument> unvalidatedConvert(const hal::V1_0::RequestArgument& argument) {
     const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
                                               : Request::Argument::LifeTime::POOL;
+    const auto location = NN_TRY(unvalidatedConvert(argument.location));
     return Request::Argument{
             .lifetime = lifetime,
-            .location = NN_TRY(unvalidatedConvert(argument.location)),
+            .location = location,
             .dimensions = argument.dimensions,
     };
 }
@@ -328,9 +338,11 @@
     pools.reserve(memories.size());
     std::move(memories.begin(), memories.end(), std::back_inserter(pools));
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
             .pools = std::move(pools),
     };
 }
@@ -500,11 +512,13 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto float32Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32)));
+    const auto quantized8Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM)));
     return Capabilities{
-            .float32Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
-            .quantized8Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
+            .float32Performance = float32Performance,
+            .quantized8Performance = quantized8Performance,
     };
 }
 
@@ -517,20 +531,24 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
+            .lifetime = lifetime,
+            .location = location,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -572,13 +590,16 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
     };
 }
 
@@ -589,9 +610,10 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
     const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
+    const auto location = NN_TRY(unvalidatedConvert(requestArgument.location));
     return RequestArgument{
             .hasNoValue = hasNoValue,
-            .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
+            .location = location,
             .dimensions = requestArgument.dimensions,
     };
 }
@@ -606,10 +628,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp
index 5bdbe31..887c8ec 100644
--- a/neuralnetworks/1.1/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.1/utils/src/Conversions.cpp
@@ -88,8 +88,9 @@
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_1::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -110,17 +111,20 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
     };
 }
@@ -195,19 +199,23 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto float32Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32)));
+    const auto quanitized8Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM)));
+    const auto relaxedFloat32toFloat16Performance =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
     return Capabilities{
-            .float32Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
-            .quantized8Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
-            .relaxedFloat32toFloat16Performance = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .float32Performance = float32Performance,
+            .quantized8Performance = quanitized8Performance,
+            .relaxedFloat32toFloat16Performance = relaxedFloat32toFloat16Performance,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -229,13 +237,16 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
     };
 }
diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp
index 62ec2ed..78d71cf 100644
--- a/neuralnetworks/1.2/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.2/utils/src/Conversions.cpp
@@ -131,15 +131,18 @@
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -154,14 +157,18 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -196,19 +203,23 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -248,9 +259,10 @@
 }
 
 GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
@@ -406,35 +418,41 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
-    std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
-    operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+    std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
+    filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
     std::copy_if(capabilities.operandPerformance.asVector().begin(),
                  capabilities.operandPerformance.asVector().end(),
-                 std::back_inserter(operandPerformance),
+                 std::back_inserter(filteredOperandPerformances),
                  [](const nn::Capabilities::OperandPerformance& operandPerformance) {
                      return compliantVersion(operandPerformance.type).has_value();
                  });
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .operandPerformance = std::move(operandPerformance),
     };
 }
 
 nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -449,15 +467,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -482,15 +504,19 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -524,9 +550,10 @@
 }
 
 nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp
index 09e9d80..4eeb414 100644
--- a/neuralnetworks/1.3/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.3/utils/src/Conversions.cpp
@@ -133,28 +133,35 @@
     auto table =
             NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
             .operandPerformance = std::move(table),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_3::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -166,25 +173,34 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_3::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
 GeneralResult<Model> unvalidatedConvert(const hal::V1_3::Model& model) {
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -204,8 +220,9 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
     return Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = subgraph.inputIndexes,
             .outputIndexes = subgraph.outputIndexes,
@@ -225,10 +242,13 @@
 }
 
 GeneralResult<Request> unvalidatedConvert(const hal::V1_3::Request& request) {
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
@@ -463,37 +483,45 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
-    std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
-    operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+    std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
+    filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
     std::copy_if(capabilities.operandPerformance.asVector().begin(),
                  capabilities.operandPerformance.asVector().end(),
-                 std::back_inserter(operandPerformance),
+                 std::back_inserter(filteredOperandPerformances),
                  [](const nn::Capabilities::OperandPerformance& operandPerformance) {
                      return compliantVersion(operandPerformance.type).has_value();
                  });
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .operandPerformance = std::move(operandPerformance),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -509,15 +537,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -527,13 +559,18 @@
                << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -548,9 +585,10 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
     return Subgraph{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
+            .operations = std::move(operations),
             .inputIndexes = subgraph.inputIndexes,
             .outputIndexes = subgraph.outputIndexes,
     };
@@ -574,10 +612,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 081e3d7..47c72b4 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -177,22 +177,28 @@
     auto table =
             NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
             .operandPerformance = std::move(table),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const aidl_hal::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
@@ -228,10 +234,13 @@
 }
 
 GeneralResult<Operation> unvalidatedConvert(const aidl_hal::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
+    auto inputs = NN_TRY(toUnsigned(operation.inputs));
+    auto outputs = NN_TRY(toUnsigned(operation.outputs));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
-            .inputs = NN_TRY(toUnsigned(operation.inputs)),
-            .outputs = NN_TRY(toUnsigned(operation.outputs)),
+            .type = type,
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
     };
 }
 
@@ -241,14 +250,19 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const aidl_hal::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    auto dimensions = NN_TRY(toUnsigned(operand.dimensions));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
-            .dimensions = NN_TRY(toUnsigned(operand.dimensions)),
+            .type = type,
+            .dimensions = std::move(dimensions),
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -280,22 +294,31 @@
 }
 
 GeneralResult<Model> unvalidatedConvert(const aidl_hal::Model& model) {
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
 GeneralResult<Model::Subgraph> unvalidatedConvert(const aidl_hal::Subgraph& subgraph) {
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
+    auto inputIndexes = NN_TRY(toUnsigned(subgraph.inputIndexes));
+    auto outputIndexes = NN_TRY(toUnsigned(subgraph.outputIndexes));
     return Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
-            .inputIndexes = NN_TRY(toUnsigned(subgraph.inputIndexes)),
-            .outputIndexes = NN_TRY(toUnsigned(subgraph.outputIndexes)),
+            .operands = std::move(operands),
+            .operations = std::move(operations),
+            .inputIndexes = std::move(inputIndexes),
+            .outputIndexes = std::move(outputIndexes),
     };
 }
 
@@ -308,9 +331,10 @@
 }
 
 GeneralResult<Extension> unvalidatedConvert(const aidl_hal::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
@@ -326,8 +350,9 @@
 }
 
 GeneralResult<OutputShape> unvalidatedConvert(const aidl_hal::OutputShape& outputShape) {
+    auto dimensions = NN_TRY(toUnsigned(outputShape.dimensions));
     return OutputShape{
-            .dimensions = NN_TRY(toUnsigned(outputShape.dimensions)),
+            .dimensions = std::move(dimensions),
             .isSufficient = outputShape.isSufficient,
     };
 }
@@ -346,8 +371,9 @@
                 return NN_ERROR() << "Memory: size must be <= std::numeric_limits<size_t>::max()";
             }
 
+            auto fd = NN_TRY(dupFd(ashmem.fd.get()));
             auto handle = Memory::Ashmem{
-                    .fd = NN_TRY(dupFd(ashmem.fd.get())),
+                    .fd = std::move(fd),
                     .size = static_cast<size_t>(ashmem.size),
             };
             return std::make_shared<const Memory>(Memory{.handle = std::move(handle)});
@@ -426,7 +452,8 @@
 }
 
 GeneralResult<BufferDesc> unvalidatedConvert(const aidl_hal::BufferDesc& bufferDesc) {
-    return BufferDesc{.dimensions = NN_TRY(toUnsigned(bufferDesc.dimensions))};
+    auto dimensions = NN_TRY(toUnsigned(bufferDesc.dimensions));
+    return BufferDesc{.dimensions = std::move(dimensions)};
 }
 
 GeneralResult<BufferRole> unvalidatedConvert(const aidl_hal::BufferRole& bufferRole) {
@@ -440,20 +467,25 @@
 }
 
 GeneralResult<Request> unvalidatedConvert(const aidl_hal::Request& request) {
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
 GeneralResult<Request::Argument> unvalidatedConvert(const aidl_hal::RequestArgument& argument) {
     const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
                                               : Request::Argument::LifeTime::POOL;
+    const auto location = NN_TRY(unvalidatedConvert(argument.location));
+    auto dimensions = NN_TRY(toUnsigned(argument.dimensions));
     return Request::Argument{
             .lifetime = lifetime,
-            .location = NN_TRY(unvalidatedConvert(argument.location)),
-            .dimensions = NN_TRY(toUnsigned(argument.dimensions)),
+            .location = location,
+            .dimensions = std::move(dimensions),
     };
 }
 
@@ -720,8 +752,9 @@
 
 nn::GeneralResult<OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
-    return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-                              .info = NN_TRY(unvalidatedConvert(operandPerformance.info))};
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
+    return OperandPerformance{.type = type, .info = info};
 }
 
 nn::GeneralResult<std::vector<OperandPerformance>> unvalidatedConvert(
@@ -788,7 +821,8 @@
 }
 
 nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc) {
-    return BufferDesc{.dimensions = NN_TRY(toSigned(bufferDesc.dimensions))};
+    auto dimensions = NN_TRY(toSigned(bufferDesc.dimensions));
+    return BufferDesc{.dimensions = std::move(dimensions)};
 }
 
 nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole) {
@@ -847,7 +881,8 @@
 }
 
 nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
-    return OutputShape{.dimensions = NN_TRY(toSigned(outputShape.dimensions)),
+    auto dimensions = NN_TRY(toSigned(outputShape.dimensions));
+    return OutputShape{.dimensions = std::move(dimensions),
                        .isSufficient = outputShape.isSufficient};
 }
 
@@ -915,14 +950,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    auto dimensions = NN_TRY(toSigned(operand.dimensions));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
-            .dimensions = NN_TRY(toSigned(operand.dimensions)),
+            .type = type,
+            .dimensions = std::move(dimensions),
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -934,19 +974,26 @@
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
+    auto inputs = NN_TRY(toSigned(operation.inputs));
+    auto outputs = NN_TRY(toSigned(operation.outputs));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
-            .inputs = NN_TRY(toSigned(operation.inputs)),
-            .outputs = NN_TRY(toSigned(operation.outputs)),
+            .type = type,
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
     };
 }
 
 nn::GeneralResult<Subgraph> unvalidatedConvert(const nn::Model::Subgraph& subgraph) {
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
+    auto inputIndexes = NN_TRY(toSigned(subgraph.inputIndexes));
+    auto outputIndexes = NN_TRY(toSigned(subgraph.outputIndexes));
     return Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
-            .inputIndexes = NN_TRY(toSigned(subgraph.inputIndexes)),
-            .outputIndexes = NN_TRY(toSigned(subgraph.outputIndexes)),
+            .operands = std::move(operands),
+            .operations = std::move(operations),
+            .inputIndexes = std::move(inputIndexes),
+            .outputIndexes = std::move(outputIndexes),
     };
 }
 
@@ -969,13 +1016,18 @@
                << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -989,10 +1041,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
@@ -1003,10 +1058,12 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
     const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
+    const auto location = NN_TRY(unvalidatedConvert(requestArgument.location));
+    auto dimensions = NN_TRY(toSigned(requestArgument.dimensions));
     return RequestArgument{
             .hasNoValue = hasNoValue,
-            .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
-            .dimensions = NN_TRY(toSigned(requestArgument.dimensions)),
+            .location = location,
+            .dimensions = std::move(dimensions),
     };
 }
 
@@ -1033,9 +1090,11 @@
 }
 
 nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
+    const auto timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice));
+    const auto timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver));
     return Timing{
-            .timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice)),
-            .timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver)),
+            .timeOnDeviceNs = timeOnDeviceNs,
+            .timeInDriverNs = timeInDriverNs,
     };
 }
 
@@ -1064,20 +1123,25 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .operandPerformance = std::move(operandPerformance),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
-    return Extension{.name = extension.name,
-                     .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))};
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
+    return Extension{.name = extension.name, .operandTypes = std::move(operandTypes)};
 }
 #ifdef NN_AIDL_V4_OR_ABOVE
 nn::GeneralResult<TokenValuePair> unvalidatedConvert(const nn::TokenValuePair& tokenValuePair) {
diff --git a/neuralnetworks/aidl/utils/src/Utils.cpp b/neuralnetworks/aidl/utils/src/Utils.cpp
index 76a0b07..f9b4f6e 100644
--- a/neuralnetworks/aidl/utils/src/Utils.cpp
+++ b/neuralnetworks/aidl/utils/src/Utils.cpp
@@ -51,8 +51,9 @@
 }
 
 nn::GeneralResult<common::NativeHandle> clone(const common::NativeHandle& handle) {
+    auto fds = NN_TRY(cloneVec(handle.fds));
     return common::NativeHandle{
-            .fds = NN_TRY(cloneVec(handle.fds)),
+            .fds = std::move(fds),
             .ints = handle.ints,
     };
 }
@@ -63,29 +64,32 @@
     switch (memory.getTag()) {
         case Memory::Tag::ashmem: {
             const auto& ashmem = memory.get<Memory::Tag::ashmem>();
+            auto fd = NN_TRY(clone(ashmem.fd));
             auto handle = common::Ashmem{
-                    .fd = NN_TRY(clone(ashmem.fd)),
+                    .fd = std::move(fd),
                     .size = ashmem.size,
             };
             return Memory::make<Memory::Tag::ashmem>(std::move(handle));
         }
         case Memory::Tag::mappableFile: {
             const auto& memFd = memory.get<Memory::Tag::mappableFile>();
+            auto fd = NN_TRY(clone(memFd.fd));
             auto handle = common::MappableFile{
                     .length = memFd.length,
                     .prot = memFd.prot,
-                    .fd = NN_TRY(clone(memFd.fd)),
+                    .fd = std::move(fd),
                     .offset = memFd.offset,
             };
             return Memory::make<Memory::Tag::mappableFile>(std::move(handle));
         }
         case Memory::Tag::hardwareBuffer: {
             const auto& hardwareBuffer = memory.get<Memory::Tag::hardwareBuffer>();
-            auto handle = graphics::common::HardwareBuffer{
+            auto handle = NN_TRY(clone(hardwareBuffer.handle));
+            auto ahwbHandle = graphics::common::HardwareBuffer{
                     .description = hardwareBuffer.description,
-                    .handle = NN_TRY(clone(hardwareBuffer.handle)),
+                    .handle = std::move(handle),
             };
-            return Memory::make<Memory::Tag::hardwareBuffer>(std::move(handle));
+            return Memory::make<Memory::Tag::hardwareBuffer>(std::move(ahwbHandle));
         }
     }
     return (NN_ERROR() << "Unrecognized Memory::Tag: " << underlyingType(memory.getTag()))
@@ -109,19 +113,21 @@
 }
 
 nn::GeneralResult<Request> clone(const Request& request) {
+    auto pools = NN_TRY(clone(request.pools));
     return Request{
             .inputs = request.inputs,
             .outputs = request.outputs,
-            .pools = NN_TRY(clone(request.pools)),
+            .pools = std::move(pools),
     };
 }
 
 nn::GeneralResult<Model> clone(const Model& model) {
+    auto pools = NN_TRY(clone(model.pools));
     return Model{
             .main = model.main,
             .referenced = model.referenced,
             .operandValues = model.operandValues,
-            .pools = NN_TRY(clone(model.pools)),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
             .extensionNameToPrefix = model.extensionNameToPrefix,
     };
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 40f6cd1..dcf8451 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -659,6 +659,7 @@
                 ASSERT_NE(nullptr, burst.get());
 
                 // associate a unique slot with each memory pool
+                constexpr int64_t kIgnoreSlot = -1;
                 int64_t currentSlot = 0;
                 std::vector<int64_t> slots;
                 slots.reserve(request.pools.size());
@@ -667,7 +668,7 @@
                         slots.push_back(currentSlot++);
                     } else {
                         EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token);
-                        slots.push_back(-1);
+                        slots.push_back(kIgnoreSlot);
                     }
                 }
 
@@ -698,8 +699,10 @@
                 // Mark each slot as unused after the execution. This is unnecessary because the
                 // burst is freed after this scope ends, but this is here to test the functionality.
                 for (int64_t slot : slots) {
-                    ret = burst->releaseMemoryResource(slot);
-                    ASSERT_TRUE(ret.isOk()) << ret.getDescription();
+                    if (slot != kIgnoreSlot) {
+                        ret = burst->releaseMemoryResource(slot);
+                        ASSERT_TRUE(ret.isOk()) << ret.getDescription();
+                    }
                 }
 
                 break;
diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
index 1b90a1a..453ec9b 100644
--- a/neuralnetworks/utils/adapter/aidl/src/Device.cpp
+++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
@@ -135,16 +135,26 @@
     return ndk::SharedRefBase::make<PreparedModel>(std::move(preparedModel));
 }
 
+void notify(IPreparedModelCallback* callback, ErrorStatus status,
+            const std::shared_ptr<IPreparedModel>& preparedModel) {
+    if (callback != nullptr) {
+        const auto ret = callback->notify(status, preparedModel);
+        if (!ret.isOk()) {
+            LOG(ERROR) << "IPreparedModelCallback::notify failed with " << ret.getDescription();
+        }
+    }
+}
+
 void notify(IPreparedModelCallback* callback, PrepareModelResult result) {
     if (!result.has_value()) {
         const auto& [message, status] = result.error();
         LOG(ERROR) << message;
         const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback, aidlCode, nullptr);
     } else {
         auto preparedModel = std::move(result).value();
         auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel));
-        callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel));
+        notify(callback, ErrorStatus::NONE, std::move(aidlPreparedModel));
     }
 }
 
@@ -284,7 +294,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
@@ -300,7 +310,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
@@ -317,7 +327,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index c5a3a8b..e1808af 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -10,6 +10,7 @@
 aidl_interface {
     name: "android.hardware.radio",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/*.aidl"],
     stability: "vintf",
     backend: {
@@ -30,6 +31,7 @@
 aidl_interface {
     name: "android.hardware.radio.config",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/config/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
@@ -51,6 +53,7 @@
 aidl_interface {
     name: "android.hardware.radio.data",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/data/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
@@ -72,6 +75,7 @@
 aidl_interface {
     name: "android.hardware.radio.messaging",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/messaging/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
@@ -93,6 +97,7 @@
 aidl_interface {
     name: "android.hardware.radio.modem",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/modem/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
@@ -114,6 +119,7 @@
 aidl_interface {
     name: "android.hardware.radio.network",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/network/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
@@ -135,6 +141,7 @@
 aidl_interface {
     name: "android.hardware.radio.sim",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/sim/*.aidl"],
     stability: "vintf",
     imports: [
@@ -159,6 +166,7 @@
 aidl_interface {
     name: "android.hardware.radio.voice",
     vendor_available: true,
+    host_supported: true,
     srcs: ["android/hardware/radio/voice/*.aidl"],
     stability: "vintf",
     imports: ["android.hardware.radio"],
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
index c60200c..db3a4c6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.config;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PhoneCapability {
   byte maxActiveData;
   byte maxActiveInternetData;
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 5cc9017..b5d31ad 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.config;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SimPortInfo {
   String iccId;
   int logicalSlotId;
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 bc7f63c..be4c080 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.config;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SimSlotStatus {
   int cardState;
   String atr;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
index f38c421..31271ee 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.config;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SlotPortMapping {
   int physicalSlotId;
   int portId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
index 929cfe3..86272c2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ApnAuthType {
   NO_PAP_NO_CHAP = 0,
   PAP_NO_CHAP = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
index 980b042..1518a57 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ApnTypes {
   NONE = 0,
   DEFAULT = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
index 6130e71..d7d6983 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum DataCallFailCause {
   NONE = 0,
   OPERATOR_BARRED = 8,
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 02bbf21..16fada1 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable DataProfileInfo {
   int profileId;
   String apn;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl
index c94fa6f..0ddaff1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum DataRequestReason {
   NORMAL = 1,
   SHUTDOWN = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
index c0ade45..4f976cd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="byte") @VintfStability
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
 enum DataThrottlingAction {
   NO_DATA_THROTTLING = 0,
   THROTTLE_SECONDARY_CARRIER = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
index 3636731..5b9aaa0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable EpsQos {
   int qci;
   android.hardware.radio.data.QosBandwidth downlink;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
index 788adfb..592a54a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable KeepaliveRequest {
   int type;
   byte[] sourceAddress;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
index 4729b8e..82b0fc8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable KeepaliveStatus {
   int sessionHandle;
   int code;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
index 9aee44c..48e646e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LinkAddress {
   String address;
   int addressProperties;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
index a8a1696..62f6204 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NrQos {
   int fiveQi;
   android.hardware.radio.data.QosBandwidth downlink;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
index 205b1e9..8595d52 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable OsAppId {
   byte[] osAppId;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
index edfa759..033b12f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PcoDataInfo {
   int cid;
   String bearerProto;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
index 363cdf3..9771e5c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PdpProtocolType {
   UNKNOWN = -1,
   IP = 0,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
index f3749ed..470a9c1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PortRange {
   int start;
   int end;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
index 1981721..ca06e41 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union Qos {
   boolean noinit;
   android.hardware.radio.data.EpsQos eps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
index d7ebe10..6d4b7a9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable QosBandwidth {
   int maxBitrateKbps;
   int guaranteedBitrateKbps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
index b9098f7..e22b359 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable QosFilter {
   String[] localAddresses;
   String[] remoteAddresses;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
index 565e499..4b75340 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union QosFilterIpsecSpi {
   boolean noinit;
   int value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
index 16117b2..3fb34ea 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union QosFilterIpv6FlowLabel {
   boolean noinit;
   int value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
index 95fda16..fa85b5a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union QosFilterTypeOfService {
   boolean noinit;
   byte value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
index 53dcef0..bbfdd2d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable QosSession {
   int qosSessionId;
   android.hardware.radio.data.Qos qos;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index 02596a1..434ee7d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RouteSelectionDescriptor {
   byte precedence;
   android.hardware.radio.data.PdpProtocolType sessionType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
index ff2459c..83f9db6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SetupDataCallResult {
   android.hardware.radio.data.DataCallFailCause cause;
   long suggestedRetryTime;
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 0dd8127..efe4816 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SliceInfo {
   byte sliceServiceType;
   int sliceDifferentiator;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
index 54e2f12..b00febe 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SlicingConfig {
   android.hardware.radio.data.UrspRule[] urspRules;
   android.hardware.radio.data.SliceInfo[] sliceInfo;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
index d5079c1..d7b0654 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable TrafficDescriptor {
   @nullable String dnn;
   @nullable android.hardware.radio.data.OsAppId osAppId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
index c0be054..7002fd1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.data;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable UrspRule {
   int precedence;
   android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
index 54e8a7b..39e2be2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaBroadcastSmsConfigInfo {
   int serviceCategory;
   int language;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
index 0de1688..befdbde 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsAck {
   boolean errorClass;
   int smsCauseCode;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
index 4a55745..ab29c77 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsAddress {
   int digitMode;
   boolean isNumberModeDataNetwork;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
index fdb74fb..867596c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsMessage {
   int teleserviceId;
   boolean isServicePresent;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
index deb1102..d67fe8c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsSubaddress {
   int subaddressType;
   boolean odd;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
index 4969663..b0a7f98 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsWriteArgs {
   int status;
   android.hardware.radio.messaging.CdmaSmsMessage message;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
index 6cc7636..46604ca 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable GsmBroadcastSmsConfigInfo {
   int fromServiceId;
   int toServiceId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
index 2937d5c..4df7fd2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable GsmSmsMessage {
   String smscPdu;
   String pdu;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
index 706bfdd..85f62b7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable ImsSmsMessage {
   android.hardware.radio.RadioTechnologyFamily tech;
   boolean retry;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
index 0fbec6f..32f7a5c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SendSmsResult {
   int messageRef;
   String ackPDU;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
index b1f8ff8..019b185 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SmsAcknowledgeFailCause {
   MEMORY_CAPACITY_EXCEEDED = 211,
   UNSPECIFIED_ERROR = 255,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
index 1748b62..489cc07 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.messaging;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SmsWriteArgs {
   int status;
   String pdu;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
index 93940fd..7e22ee0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable ActivityStatsInfo {
   int sleepModeTimeMs;
   int idleModeTimeMs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
index 798ec36..08ed9a5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable ActivityStatsTechSpecificInfo {
   android.hardware.radio.AccessNetwork rat;
   int frequencyRange;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
index 0f0006d..4e8c6d7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum DeviceStateType {
   POWER_SAVE_MODE = 0,
   CHARGING_STATE = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
index 7593ca7..3a0ec25 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable HardwareConfig {
   int type;
   String uuid;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
index bf70995..62bb160 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable HardwareConfigModem {
   int rilModel;
   android.hardware.radio.RadioTechnology rat;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
index 1b887c2..5810982 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable HardwareConfigSim {
   String modemUuid;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
index bda4ab7..3e27643 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum NvItem {
   CDMA_MEID = 1,
   CDMA_MIN = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
index 58e8498..17b7de0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NvWriteItem {
   android.hardware.radio.modem.NvItem itemId;
   String value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
index 5aaf5a7..f2e2858 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RadioCapability {
   int session;
   int phase;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl
index 4bde770..57f2941 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioState {
   OFF = 0,
   UNAVAILABLE = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
index 81f2254..e3b5796 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ResetNvType {
   RELOAD = 0,
   ERASE = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
index 4a4a120..28d8862 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union AccessTechnologySpecificInfo {
   boolean noinit;
   android.hardware.radio.network.Cdma2000RegistrationInfo cdmaInfo;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
index a96ef51..e105b39 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable BarringInfo {
   int serviceType;
   int barringType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
index c04cdb5..a813633 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable BarringTypeSpecificInfo {
   int factor;
   int timeSeconds;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 7d9292d..74c4e29 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable Cdma2000RegistrationInfo {
   boolean cssSupported;
   int roamingIndicator;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
index 54c431b..24ec26b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaRoamingType {
   HOME_NETWORK = 0,
   AFFILIATED_ROAM = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
index b4aee1c..e2f97bf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSignalStrength {
   int dbm;
   int ecio;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
index 066cb60..8986d71 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CellConnectionStatus {
   NONE = 0,
   PRIMARY_SERVING = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
index 1c68e8c..2ee92de 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union CellIdentity {
   boolean noinit;
   android.hardware.radio.network.CellIdentityGsm gsm;
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 8c1fdfa..d659a28 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityCdma {
   int networkId;
   int systemId;
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 2e384e9..d3193be 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityGsm {
   String mcc;
   String mnc;
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 c83997e..2ae7b43 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityLte {
   String mcc;
   String mnc;
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 6bdfd99..b30af50 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityNr {
   String mcc;
   String mnc;
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 4100805..e99d147 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityTdscdma {
   String mcc;
   String mnc;
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 907f30d..12001fc 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityWcdma {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
index 38e0a44..467c6b7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfo {
   boolean registered;
   android.hardware.radio.network.CellConnectionStatus connectionStatus;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
index d171a4b..e3bf46b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoCdma {
   android.hardware.radio.network.CellIdentityCdma cellIdentityCdma;
   android.hardware.radio.network.CdmaSignalStrength signalStrengthCdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
index 491b686..84dcd07 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoGsm {
   android.hardware.radio.network.CellIdentityGsm cellIdentityGsm;
   android.hardware.radio.network.GsmSignalStrength signalStrengthGsm;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
index 67c5a18..221340b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoLte {
   android.hardware.radio.network.CellIdentityLte cellIdentityLte;
   android.hardware.radio.network.LteSignalStrength signalStrengthLte;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
index a094600..b392c1d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoNr {
   android.hardware.radio.network.CellIdentityNr cellIdentityNr;
   android.hardware.radio.network.NrSignalStrength signalStrengthNr;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
index 4e0719c..4ab0640 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union CellInfoRatSpecificInfo {
   android.hardware.radio.network.CellInfoGsm gsm;
   android.hardware.radio.network.CellInfoWcdma wcdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
index d4e0874..138b35c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoTdscdma {
   android.hardware.radio.network.CellIdentityTdscdma cellIdentityTdscdma;
   android.hardware.radio.network.TdscdmaSignalStrength signalStrengthTdscdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
index da19e37..cf7b135 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CellInfoWcdma {
   android.hardware.radio.network.CellIdentityWcdma cellIdentityWcdma;
   android.hardware.radio.network.WcdmaSignalStrength signalStrengthWcdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
index 5c45d93..fe734c8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable ClosedSubscriberGroupInfo {
   boolean csgIndication;
   String homeNodebName;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
index 712bbdb..209cf5e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum Domain {
   CS = 1,
   PS = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl
index 6c94d15..57fac3f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum EutranBands {
   BAND_1 = 1,
   BAND_2 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
index 098b57e..dfbf881 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable EutranRegistrationInfo {
   android.hardware.radio.network.LteVopsInfo lteVopsInfo;
   android.hardware.radio.network.NrIndicators nrIndicators;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
index 7ec1635..7c56711 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable EvdoSignalStrength {
   int dbm;
   int ecio;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl
index 7cb0fd5..135935f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum GeranBands {
   BAND_T380 = 1,
   BAND_T410 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
index 4142ae7..2b53b39 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable GsmSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
index f79ff2a..d9ed68e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum IndicationFilter {
   NONE = 0,
   ALL = -1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
index 1876465..27b16c1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LceDataInfo {
   int lastHopCapacityKbps;
   byte confidenceLevel;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
index c34f177..5707b8e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LinkCapacityEstimate {
   int downlinkCapacityKbps;
   int uplinkCapacityKbps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
index c7b41f1..b5b8579 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LteSignalStrength {
   int signalStrength;
   int rsrp;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
index 9f20b10..6d8dd4e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LteVopsInfo {
   boolean isVopsSupported;
   boolean isEmcBearerSupported;
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 1e657e5..6039740 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NetworkScanRequest {
   int type;
   int interval;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
index 3dc3940..4e392d0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NetworkScanResult {
   int status;
   android.hardware.radio.RadioError error;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl
index aa60cde..5904690 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum NgranBands {
   BAND_1 = 1,
   BAND_2 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl
index 6ee526f..62c2a56 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="byte") @VintfStability
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
 enum NrDualConnectivityState {
   ENABLE = 1,
   DISABLE = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
index 54f9b8f..88429f6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NrIndicators {
   boolean isEndcAvailable;
   boolean isDcNrRestricted;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
index 14b60a6..98bbe6b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NrSignalStrength {
   int ssRsrp;
   int ssRsrq;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
index 7f58ee1..e5a0a70 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable NrVopsInfo {
   byte vopsSupported;
   byte emcSupported;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
index c3658d9..034150e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable OperatorInfo {
   String alphaLong;
   String alphaShort;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
index dff8be0..41555f9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PhoneRestrictedState {
   NONE = 0,
   CS_EMERGENCY = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
index 8db6bc4..928c6b7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PhysicalChannelConfig {
   android.hardware.radio.network.CellConnectionStatus status;
   android.hardware.radio.RadioTechnology rat;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
index 50af816..efc64a6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union PhysicalChannelConfigBand {
   boolean noinit;
   android.hardware.radio.network.GeranBands geranBand;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
index b412f63..1566bb5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RadioAccessSpecifier {
   android.hardware.radio.AccessNetwork accessNetwork;
   android.hardware.radio.network.RadioAccessSpecifierBands bands;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
index d44a883..a6ac12a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 union RadioAccessSpecifierBands {
   boolean noinit;
   android.hardware.radio.network.GeranBands[] geranBands;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
index 7266fd5..e9a9f60 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioBandMode {
   BAND_MODE_UNSPECIFIED = 0,
   BAND_MODE_EURO = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
index d10f413..e6e7999 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RegState {
   NOT_REG_MT_NOT_SEARCHING_OP = 0,
   REG_HOME = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
index eff2216..f0a03ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RegStateResult {
   android.hardware.radio.network.RegState regState;
   android.hardware.radio.RadioTechnology rat;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
index 75fcdf4..e2cd44c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RegistrationFailCause {
   NONE = 0,
   IMSI_UNKNOWN_IN_HLR = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
index 7187116..1c50190 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SignalStrength {
   android.hardware.radio.network.GsmSignalStrength gsm;
   android.hardware.radio.network.CdmaSignalStrength cdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
index 159d9c1..040932c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SignalThresholdInfo {
   int signalMeasurement;
   int hysteresisMs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
index 541754e..b62c71b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SuppSvcNotification {
   boolean isMT;
   int code;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
index a00345f..d74c950 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable TdscdmaSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
index 7fdf831..3ca16b5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum UsageSetting {
   VOICE_CENTRIC = 1,
   DATA_CENTRIC = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl
index 87d5b85..8be3da2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum UtranBands {
   BAND_1 = 1,
   BAND_2 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
index 678ace9..9112527 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.network;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable WcdmaSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
index 89d8f9a..8a41fb9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable AppStatus {
   int appType;
   int appState;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
index c0026ba..05bc13a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CardPowerState {
   POWER_DOWN = 0,
   POWER_UP = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
index cf37a0d..9000d43 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CardStatus {
   int cardState;
   android.hardware.radio.sim.PinState universalPinState;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
index c7fced1..cc56888 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable Carrier {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index 85cf86e..944f1ca 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CarrierRestrictions {
   android.hardware.radio.sim.Carrier[] allowedCarriers;
   android.hardware.radio.sim.Carrier[] excludedCarriers;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index 50e768c..13469f3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaSubscriptionSource {
   RUIM_SIM = 0,
   NV = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
index 3e4dcf6..5a312dc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable IccIo {
   int command;
   int fileId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
index 58e43eb..6c6bde2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable IccIoResult {
   int sw1;
   int sw2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
index 087f399..05e71cd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable ImsiEncryptionInfo {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl
index 61babac..5e96fc6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="byte") @VintfStability
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
 enum PbReceivedStatus {
   PB_RECEIVED_OK = 1,
   PB_RECEIVED_ERROR = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
index a09d781..e33769e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PersoSubstate {
   UNKNOWN = 0,
   IN_PROGRESS = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
index c1fa765..7531c96 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PhonebookCapacity {
   int maxAdnRecords;
   int usedAdnRecords;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
index 36bc920..2e96a4b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable PhonebookRecordInfo {
   int recordId;
   String name;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
index c78b92c..5cdc6d1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PinState {
   UNKNOWN = 0,
   ENABLED_NOT_VERIFIED = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
index 4842fbe..02121e6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SelectUiccSub {
   int slot;
   int appIndex;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index d8e1dde..2201345 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SimApdu {
   int sessionId;
   int cla;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 6fd89d5..4ded3e9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SimLockMultiSimPolicy {
   NO_MULTISIM_POLICY = 0,
   ONE_VALID_SIM_MUST_BE_PRESENT = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
index dd3c1f2..69bf476 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.sim;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SimRefreshResult {
   int type;
   int efId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
index 89bd2dc..15669ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum AudioQuality {
   UNSPECIFIED = 0,
   AMR = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
index 7f44531..10d2ee7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable Call {
   int state;
   int index;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
index 7ef9e46..8e7aaab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CallForwardInfo {
   int status;
   int reason;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
index 9edf1e7..310f9a0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaCallWaiting {
   String number;
   int numberPresentation;
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 b373aa5..b6b562c 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @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 cc4d3fa..24ae775 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaInformationRecord {
   int name;
   android.hardware.radio.voice.CdmaDisplayInfoRecord[] display;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
index d7f6cd4..e34b393 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaLineControlInfoRecord {
   byte lineCtrlPolarityIncluded;
   byte lineCtrlToggle;
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 26a7df5..aeb0347 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaNumberInfoRecord {
   String number;
   byte numberType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index 5ea4e50..7877fda 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaOtaProvisionStatus {
   SPL_UNLOCKED = 0,
   SPC_RETRIES_EXCEEDED = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
index f0f2b04..b61b91b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaRedirectingNumberInfoRecord {
   android.hardware.radio.voice.CdmaNumberInfoRecord redirectingNumber;
   int redirectingReason;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
index 2ebb396..6c7b264 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaSignalInfoRecord {
   boolean isPresent;
   byte signalType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
index 33e2c2b..438231c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaT53AudioControlInfoRecord {
   byte upLink;
   byte downLink;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
index 457fd18..1b254f5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CdmaT53ClirInfoRecord {
   byte cause;
 }
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 744e7ae..7e799c7 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @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/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
index dafc2b9..3fbb0d8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ClipStatus {
   CLIP_PROVISIONED = 0,
   CLIP_UNPROVISIONED = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
index c9a02a9..2b2e759 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable Dial {
   String address;
   int clir;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
index b31a661..07f011d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum EmergencyCallRouting {
   UNKNOWN = 0,
   EMERGENCY = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 39bcf1a..98df8cd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable EmergencyNumber {
   String number;
   String mcc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
index 34d3c40..042dd61 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum EmergencyServiceCategory {
   UNSPECIFIED = 0,
   POLICE = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
index 3e17840..1740134 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum LastCallFailCause {
   UNOBTAINABLE_NUMBER = 1,
   NO_ROUTE_TO_DESTINATION = 3,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
index af75a40..221acf7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable LastCallFailCauseInfo {
   android.hardware.radio.voice.LastCallFailCause causeCode;
   String vendorCause;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
index 8e7e9fb..864374b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SrvccState {
   HANDOVER_STARTED = 0,
   HANDOVER_COMPLETED = 1,
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 9517847..f18b404 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable SsInfoData {
   int[] ssInfo;
   const int SS_INFO_MAX = 4;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index 71ef7a7..50bb1fd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable StkCcUnsolSsResult {
   int serviceType;
   int requestType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
index bb0a9f1..77417e8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum TtyMode {
   OFF = 0,
   FULL = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
index 9a9d723..ad243d2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum UssdModeType {
   NOTIFY = 0,
   REQUEST = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
index 0198de9..9313760 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.voice;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable UusInfo {
   int uusType;
   int uusDcs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
index 0327d6c..8ce689f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum AccessNetwork {
   UNKNOWN = 0,
   GERAN = 1,
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 9bb17fe..ecc2a9b 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
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioAccessFamily {
   UNKNOWN = 1,
   GPRS = 2,
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 f411ca2..b91bf03 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,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RadioConst {
   const int MAX_RILDS = 3;
   const int MAX_UUID_LENGTH = 64;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl
index 3ef67bc..98606e5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioError {
   NONE = 0,
   RADIO_NOT_AVAILABLE = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
index fc5d4df..54ea3a4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioIndicationType {
   UNSOLICITED = 0,
   UNSOLICITED_ACK_EXP = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
index 08c3023..b2a7a06 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RadioResponseInfo {
   android.hardware.radio.RadioResponseType type;
   int serial;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
index cbc4ab9..37ed7bb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable RadioResponseInfoModem {
   android.hardware.radio.RadioResponseType type;
   int serial;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
index cf241830..5cd99c4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioResponseType {
   SOLICITED = 0,
   SOLICITED_ACK = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
index d0ca9b5..9dad0a4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioTechnology {
   UNKNOWN = 0,
   GPRS = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
index c11cd1c..e6fdce2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio;
-@Backing(type="int") @VintfStability
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioTechnologyFamily {
   THREE_GPP = 0,
   THREE_GPP2 = 1,
diff --git a/radio/aidl/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/android/hardware/radio/AccessNetwork.aidl
index 10b84f4..2885642 100644
--- a/radio/aidl/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/AccessNetwork.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum AccessNetwork {
     /**
      * Unknown access network
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index b8fbf9b..6cd0a95 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioAccessFamily {
     UNKNOWN = 1 << RadioTechnology.UNKNOWN,
     GPRS = 1 << RadioTechnology.GPRS,
diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl
index cd03f84..6591ef1 100644
--- a/radio/aidl/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/android/hardware/radio/RadioConst.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RadioConst {
     const int MAX_RILDS = 3;
     const int MAX_UUID_LENGTH = 64;
diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl
index a708d2b..ae58a0e 100644
--- a/radio/aidl/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/android/hardware/radio/RadioError.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioError {
     /**
      * Success
diff --git a/radio/aidl/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/android/hardware/radio/RadioIndicationType.aidl
index aa5215f..2dcc492 100644
--- a/radio/aidl/android/hardware/radio/RadioIndicationType.aidl
+++ b/radio/aidl/android/hardware/radio/RadioIndicationType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioIndicationType {
     UNSOLICITED,
     UNSOLICITED_ACK_EXP,
diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
index d81c49c..f70a3fe 100644
--- a/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
+++ b/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.RadioResponseType;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RadioResponseInfo {
     /**
      * Response type
diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
index 8c7b94c..13abfb9 100644
--- a/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
+++ b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.RadioResponseType;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RadioResponseInfoModem {
     /**
      * Response type
diff --git a/radio/aidl/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/android/hardware/radio/RadioResponseType.aidl
index 882c759..cd4a305 100644
--- a/radio/aidl/android/hardware/radio/RadioResponseType.aidl
+++ b/radio/aidl/android/hardware/radio/RadioResponseType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioResponseType {
     SOLICITED,
     SOLICITED_ACK,
diff --git a/radio/aidl/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
index d439866..917cb16 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioTechnology {
     UNKNOWN,
     GPRS,
diff --git a/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
index 37a1df2..a2b989d 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioTechnologyFamily {
     /**
      * 3GPP Technologies - GSM, WCDMA
diff --git a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
index bc55e39..8e4f338 100644
--- a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
@@ -22,6 +22,7 @@
  * SIM device to multi-SIM device.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PhoneCapability {
     /**
      * maxActiveData defines how many logical modems can have
diff --git a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
index 54b9890..db24719 100644
--- a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.config;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SimPortInfo {
     /**
      * Integrated Circuit Card IDentifier (ICCID) is unique identifier of the SIM card. File is
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index b5cf633..748660f 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.config.SimPortInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SimSlotStatus {
     /**
      * Card state in the physical slot. Values are CardStatus.[STATE_ABSENT, STATE_PRESENT,
diff --git a/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl b/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
index 3046d4f..c78afcb 100644
--- a/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
+++ b/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.config;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SlotPortMapping {
     /**
      * Physical slot id is the index of the slots
diff --git a/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl b/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl
index 8209dfe..a4116db 100644
--- a/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl
+++ b/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum ApnAuthType {
     /**
      * PAP and CHAP is never performed.
diff --git a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
index ae103fc..ed1256d 100644
--- a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum ApnTypes {
     /**
      * None
diff --git a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
index 89cd8f2..29ece76 100644
--- a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum DataCallFailCause {
     /**
      * An integer cause code defined in TS 24.008 section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B.
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 123b3ed..ea4e751 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.data.TrafficDescriptor;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable DataProfileInfo {
     const int ID_DEFAULT = 0;
     const int ID_TETHERED = 1;
diff --git a/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl b/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl
index 2bb5bd6..44b47f8 100644
--- a/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum DataRequestReason {
     /**
      * The reason of the data request is normal
diff --git a/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl b/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl
index dfa64e2..e4ee444 100644
--- a/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="byte")
+@JavaDerive(toString=true)
 enum DataThrottlingAction {
     /*
      * Clear all existing data throttling.
diff --git a/radio/aidl/android/hardware/radio/data/EpsQos.aidl b/radio/aidl/android/hardware/radio/data/EpsQos.aidl
index 559a153..8965d6e 100644
--- a/radio/aidl/android/hardware/radio/data/EpsQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/EpsQos.aidl
@@ -22,6 +22,7 @@
  * LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable EpsQos {
     /**
      * Quality of Service Class Identifier (QCI), see 3GPP TS 23.203 and 29.212.
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index e1ba568..0171d39 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -65,6 +65,7 @@
     /**
      * Deactivate packet data connection and remove from the data call list. An
      * unsolDataCallListChanged() must be sent when data connection is deactivated.
+     * Any return value other than RadioError::NONE will remove the network from the list.
      *
      * @param serial Serial number of request.
      * @param cid Data call id.
@@ -76,8 +77,7 @@
 
     /**
      * Returns the data call list. An entry is added when a setupDataCall() is issued and removed
-     * on a deactivateDataCall(). The list is emptied when setRadioPower()  off/on issued or when
-     * the vendor HAL or modem crashes.
+     * on a deactivateDataCall(). The list is emptied when the vendor HAL crashes.
      *
      * @param serial Serial number of request.
      *
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
index bbc8d07..88b6c1b 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -67,7 +67,7 @@
      *
      * Valid errors returned:
      *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
-     *   RadioError:NONE
+     *   RadioError:NONE indicates success. Any other error will remove the network from the list.
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
index 57c9f68..c720de0 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable KeepaliveRequest {
     /**
      * Keepalive specified by RFC 3948 Sec. 2.3 using IPv4
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
index 2df280c..0b829c4 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable KeepaliveStatus {
     /**
      * Keepalive is currently active.
diff --git a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
index 599d382..12a7637 100644
--- a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
@@ -20,6 +20,7 @@
  * Describes a data link address for mobile data connection.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LinkAddress {
     const int ADDRESS_PROPERTY_NONE = 0;
     /**
diff --git a/radio/aidl/android/hardware/radio/data/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl
index 1d69b4f..af8ab83 100644
--- a/radio/aidl/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl
@@ -22,6 +22,7 @@
  * 5G Quality of Service parameters as per 3gpp spec 24.501 sec 9.11.4.12
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NrQos {
     const byte FLOW_ID_RANGE_MIN = 1;
     const byte FLOW_ID_RANGE_MAX = 63;
diff --git a/radio/aidl/android/hardware/radio/data/OsAppId.aidl b/radio/aidl/android/hardware/radio/data/OsAppId.aidl
index 0bf6d7e..88e7832 100644
--- a/radio/aidl/android/hardware/radio/data/OsAppId.aidl
+++ b/radio/aidl/android/hardware/radio/data/OsAppId.aidl
@@ -20,6 +20,7 @@
  * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable OsAppId {
     /**
      * Byte array representing OsId + OsAppId. The minimum length of the array is 18 and maximum
diff --git a/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
index 9587614..38a821f 100644
--- a/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PcoDataInfo {
     /**
      * Context ID, uniquely identifies this call
diff --git a/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl b/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl
index 9b1136c..792a503 100644
--- a/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl
+++ b/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum PdpProtocolType {
     /**
      * Unknown protocol
diff --git a/radio/aidl/android/hardware/radio/data/PortRange.aidl b/radio/aidl/android/hardware/radio/data/PortRange.aidl
index b1f88e6..5c83ca4 100644
--- a/radio/aidl/android/hardware/radio/data/PortRange.aidl
+++ b/radio/aidl/android/hardware/radio/data/PortRange.aidl
@@ -22,6 +22,7 @@
  * be represented by the same start and end value.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PortRange {
     const int PORT_RANGE_MIN = 20;
     const int PORT_RANGE_MAX = 65535;
diff --git a/radio/aidl/android/hardware/radio/data/Qos.aidl b/radio/aidl/android/hardware/radio/data/Qos.aidl
index 3d458de..d9ab9e7 100644
--- a/radio/aidl/android/hardware/radio/data/Qos.aidl
+++ b/radio/aidl/android/hardware/radio/data/Qos.aidl
@@ -23,6 +23,7 @@
  * EPS or NR QOS parameters
  */
 @VintfStability
+@JavaDerive(toString=true)
 union Qos {
     boolean noinit;
     EpsQos eps;
diff --git a/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
index a21003a..e841548 100644
--- a/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable QosBandwidth {
     /**
      * Maximum bit rate possible on the bearer
diff --git a/radio/aidl/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/android/hardware/radio/data/QosFilter.aidl
index 626f2b4..f5dc7ec 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilter.aidl
@@ -25,6 +25,7 @@
  * See 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable QosFilter {
     const byte DIRECTION_DOWNLINK = 0;
     const byte DIRECTION_UPLINK = 1;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
index fd7efb1..5059c28 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 union QosFilterIpsecSpi {
     boolean noinit;
     int value;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
index d6ce84b..6f14934 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 union QosFilterIpv6FlowLabel {
     boolean noinit;
     int value;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
index c50c5b6..f5770a4 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 @VintfStability
+@JavaDerive(toString=true)
 union QosFilterTypeOfService {
     boolean noinit;
     byte value;
diff --git a/radio/aidl/android/hardware/radio/data/QosSession.aidl b/radio/aidl/android/hardware/radio/data/QosSession.aidl
index 389c349..770b124 100644
--- a/radio/aidl/android/hardware/radio/data/QosSession.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosSession.aidl
@@ -23,6 +23,7 @@
  * QOS session associated with a dedicated bearer
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable QosSession {
     /**
      * Unique ID of the QoS session within the data call
diff --git a/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index d9d602e..14b0ffc 100644
--- a/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -23,6 +23,7 @@
  * This struct represents a single route selection descriptor as defined in 3GPP TS 24.526.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RouteSelectionDescriptor {
     const byte SSC_MODE_UNKNOWN = -1;
     const byte SSC_MODE_1 = 1;
diff --git a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
index ebfc55d..fee54ac 100644
--- a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
+++ b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -25,6 +25,7 @@
 import android.hardware.radio.data.TrafficDescriptor;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SetupDataCallResult {
     /**
      * Indicates the data connection is inactive.
diff --git a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
index 0943031..7ad7fc3 100644
--- a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
@@ -20,6 +20,7 @@
  * This struct represents a S-NSSAI as defined in 3GPP TS 24.501.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SliceInfo {
     /*
      * Not specified
diff --git a/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
index eea2d49..e94b58c 100644
--- a/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
+++ b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
@@ -23,6 +23,7 @@
  * This struct represents the current slicing configuration.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SlicingConfig {
     /**
      * This vector contains the current URSP rules. Empty vector indicates no rules are configured.
diff --git a/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
index e6ea27c..2c117a5 100644
--- a/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
+++ b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
@@ -24,6 +24,7 @@
  * TS 24.526 Section 5.2.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable TrafficDescriptor {
     /**
      * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003.
diff --git a/radio/aidl/android/hardware/radio/data/UrspRule.aidl b/radio/aidl/android/hardware/radio/data/UrspRule.aidl
index de85be5..0499edd 100644
--- a/radio/aidl/android/hardware/radio/data/UrspRule.aidl
+++ b/radio/aidl/android/hardware/radio/data/UrspRule.aidl
@@ -23,6 +23,7 @@
  * This struct represents a single URSP rule as defined in 3GPP TS 24.526.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable UrspRule {
     /**
      * Precedence value in the range of 0 to 255. Higher value has lower precedence.
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
index 3d715e2..4173f15 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaBroadcastSmsConfigInfo {
     /**
      * Defines a broadcast message identifier whose value is 0x0000 - 0xFFFF as defined in
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
index 25871c8..85ef692 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSmsAck {
     boolean errorClass;
     /**
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
index 835dda5..8e521df 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSmsAddress {
     /**
      * DTMF digits
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
index f1f065f..d4fb26f 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.messaging.CdmaSmsSubaddress;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSmsMessage {
     int teleserviceId;
     boolean isServicePresent;
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
index 9dfe503..18e5837 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSmsSubaddress {
     /**
      * CCITT X.213 or ISO 8348 AD2
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
index e73a0d7..4191985 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.messaging.CdmaSmsMessage;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSmsWriteArgs {
     const int STATUS_REC_UNREAD = 0;
     const int STATUS_REC_READ = 1;
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
index 2a52f0a..5138c3c 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
@@ -20,6 +20,7 @@
  * Which types of Cell Broadcast Message (CBM) are to be received by the ME
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable GsmBroadcastSmsConfigInfo {
     /**
      * Beginning of the range of CBM message identifiers whose value is 0x0000 - 0xFFFF as defined
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
index 45c09af..ee62d95 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable GsmSmsMessage {
     /**
      * SMSC address in GSM BCD format prefixed by a length byte (as expected by TS 27.005)
diff --git a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
index 809cfb3..d4be044 100644
--- a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.messaging.GsmSmsMessage;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable ImsSmsMessage {
     RadioTechnologyFamily tech;
     /**
diff --git a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
index 15d68f1..80e059c 100644
--- a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SendSmsResult {
     /**
      * TP-Message-Reference for GSM, and BearerData MessageId for CDMA.
diff --git a/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl b/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
index a47cdb6..eb15bf1 100644
--- a/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum SmsAcknowledgeFailCause {
     MEMORY_CAPACITY_EXCEEDED = 0xD3,
     UNSPECIFIED_ERROR = 0XFF,
diff --git a/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
index 539f68b..6eef941 100644
--- a/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.messaging;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SmsWriteArgs {
     const int STATUS_REC_UNREAD = 0;
     const int STATUS_REC_READ = 1;
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
index d0aa695..b2a56d4 100644
--- a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.modem.ActivityStatsTechSpecificInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable ActivityStatsInfo {
     /**
      * Total time (in ms) when modem is in a low power or sleep state
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
index fb14223..fcc2df2 100644
--- a/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.AccessNetwork;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable ActivityStatsTechSpecificInfo {
     /** Indicates the frequency range is unknown. */
     const int FREQUENCY_RANGE_UNKNOWN = 0;
diff --git a/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl b/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl
index 0dae351..ad0d59c 100644
--- a/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl
+++ b/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum DeviceStateType {
     /**
      * Device power save mode (provided by PowerManager). True indicates the device is in
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
index c38df5e..8eb1f2d 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.modem.HardwareConfigSim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable HardwareConfig {
     const int STATE_ENABLED = 0;
     const int STATE_STANDBY = 1;
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
index 0b7343b..f5e2c27 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.RadioTechnology;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable HardwareConfigModem {
     /**
      * RIL attachment model. Values are:
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
index 0f0c05f..c82bc6e 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.modem;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable HardwareConfigSim {
     /**
      * RadioConst:MAX_UUID_LENGTH is max length of the string
diff --git a/radio/aidl/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
index cdae1c8..649b0d2 100644
--- a/radio/aidl/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum NvItem {
     /**
      * CDMA radio and account information (items 1-10)
diff --git a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
index d66c2cd..47fb490 100644
--- a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.modem.NvItem;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NvWriteItem {
     NvItem itemId;
     String value;
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index 96b9d0d..16cba09 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.modem;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RadioCapability {
     /**
      * Logical Modem's (LM) initial value and value after PHASE_FINISH completes.
diff --git a/radio/aidl/android/hardware/radio/modem/RadioState.aidl b/radio/aidl/android/hardware/radio/modem/RadioState.aidl
index b9826a4..dedad25 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioState.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioState.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioState {
     /**
      * Radio explicitly powered off (eg CFUN=0)
diff --git a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
index a1411c9..16487f8 100644
--- a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum ResetNvType {
     /**
      * Reload all NV items
diff --git a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
index dfd62a7..8b95ced 100644
--- a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.network.NrVopsInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 union AccessTechnologySpecificInfo {
     boolean noinit;
     Cdma2000RegistrationInfo cdmaInfo;
diff --git a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
index da49ba5..2759406 100644
--- a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.network.BarringTypeSpecificInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable BarringInfo {
     /**
      * Device is not barred for the given service
diff --git a/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
index 3899711..3db3bf3 100644
--- a/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable BarringTypeSpecificInfo {
     /**
      * The barring factor as a percentage 0-100
diff --git a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 6ea6cf9..b06fabb 100644
--- a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable Cdma2000RegistrationInfo {
     const int PRL_INDICATOR_NOT_REGISTERED = -1;
     const int PRL_INDICATOR_NOT_IN_PRL = 0;
diff --git a/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
index 3da8c98..2fea519 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum CdmaRoamingType {
     HOME_NETWORK,
     AFFILIATED_ROAM,
diff --git a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
index c7754f2..1286f67 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
diff --git a/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl b/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl
index d9f5766..da36ff0 100644
--- a/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum CellConnectionStatus {
     /**
      * Cell is not a serving cell.
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
index af6d38e..e34866b 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
@@ -27,6 +27,7 @@
  * A union representing the CellIdentity of a single cell.
  */
 @VintfStability
+@JavaDerive(toString=true)
 union CellIdentity {
     boolean noinit;
     CellIdentityGsm gsm;
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index ae6fda4..5bb26c1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityCdma {
     /**
      * Network Id 0..65535, INT_MAX if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
index 75a96e8..60f42b6 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityGsm {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
index ae52cf2..bfa58ac 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityLte {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
index 73a56ea..d51a18e 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
@@ -24,6 +24,7 @@
  * broadcast in SIB1 CellAccessRelatedInfo as per 3GPP TS 38.331 Section 6.3.2.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityNr {
     /**
      * 3-digit Mobile Country Code, in range[0, 999]; This value must be valid for registered or
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 5b00df1..f6e790f 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityTdscdma {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown.
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
index bf4d6cb..a76509b 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.OperatorInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellIdentityWcdma {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfo.aidl
index 58cf9f5..161ac71 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfo.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.CellInfoRatSpecificInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfo {
     /**
      * True if this cell is registered false if not registered.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
index 6d92918..5408104 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.network.EvdoSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoCdma {
     CellIdentityCdma cellIdentityCdma;
     CdmaSignalStrength signalStrengthCdma;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
index fc85248..cadcd91 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.GsmSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoGsm {
     CellIdentityGsm cellIdentityGsm;
     GsmSignalStrength signalStrengthGsm;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
index 22db722..443a668 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.LteSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoLte {
     CellIdentityLte cellIdentityLte;
     LteSignalStrength signalStrengthLte;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
index fbf026e..6b3d4f4 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.NrSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoNr {
     CellIdentityNr cellIdentityNr;
     NrSignalStrength signalStrengthNr;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
index 7e8a437..76e92a4 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -24,6 +24,7 @@
 import android.hardware.radio.network.CellInfoWcdma;
 
 @VintfStability
+@JavaDerive(toString=true)
 union CellInfoRatSpecificInfo {
     /**
      * 3gpp CellInfo types.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
index e07e721..fb9c984 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.TdscdmaSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoTdscdma {
     CellIdentityTdscdma cellIdentityTdscdma;
     TdscdmaSignalStrength signalStrengthTdscdma;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
index 38b6903..2d6a2e5 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.WcdmaSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CellInfoWcdma {
     CellIdentityWcdma cellIdentityWcdma;
     WcdmaSignalStrength signalStrengthWcdma;
diff --git a/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
index b5b4add..a2d82d7 100644
--- a/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable ClosedSubscriberGroupInfo {
     /**
      * Indicates whether the cell is restricted to only CSG members. A cell not broadcasting the
diff --git a/radio/aidl/android/hardware/radio/network/Domain.aidl b/radio/aidl/android/hardware/radio/network/Domain.aidl
index b62f0ee..be5f320 100644
--- a/radio/aidl/android/hardware/radio/network/Domain.aidl
+++ b/radio/aidl/android/hardware/radio/network/Domain.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum Domain {
     /**
      * Circuit-switched
diff --git a/radio/aidl/android/hardware/radio/network/EutranBands.aidl b/radio/aidl/android/hardware/radio/network/EutranBands.aidl
index 48ee26e..72e76e3 100644
--- a/radio/aidl/android/hardware/radio/network/EutranBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/EutranBands.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum EutranBands {
     BAND_1 = 1,
     BAND_2 = 2,
diff --git a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
index 5e19c56..c9563ac 100644
--- a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.NrIndicators;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable EutranRegistrationInfo {
     /**
      * Network capabilities for voice over PS services. This info is valid only on LTE network and
diff --git a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
index 0ab8b59..c3b3898 100644
--- a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable EvdoSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
diff --git a/radio/aidl/android/hardware/radio/network/GeranBands.aidl b/radio/aidl/android/hardware/radio/network/GeranBands.aidl
index 573d771..0e5b7b2 100644
--- a/radio/aidl/android/hardware/radio/network/GeranBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/GeranBands.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum GeranBands {
     BAND_T380 = 1,
     BAND_T410 = 2,
diff --git a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
index 539e1ce..796f80f 100644
--- a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable GsmSignalStrength {
     /**
      * Valid values are (0-61, 99) as defined in TS 27.007 8.69; INT_MAX means invalid/unreported.
diff --git a/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl b/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl
index ac48227..9cab28d 100644
--- a/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl
+++ b/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum IndicationFilter {
     NONE = 0,
     ALL = ~0,
diff --git a/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
index 344227e..fdbdc2b 100644
--- a/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LceDataInfo {
     /**
      * Last-hop cellular capacity: kilobits/second.
diff --git a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
index 8d31bbc..6461719 100644
--- a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
+++ b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LinkCapacityEstimate {
     /**
      * Estimated downlink capacity in kbps. In case of a dual connected network, this includes
diff --git a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
index a727aa5..2d97c45 100644
--- a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LteSignalStrength {
     /**
      * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported.
diff --git a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
index 1cda8db..fb3b986 100644
--- a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
@@ -21,6 +21,7 @@
  * normal voice calls.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LteVopsInfo {
     /**
      * This indicates if camped network support VoLTE services. This information is received from
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
index 7cea1de..ae173c7 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.network.RadioAccessSpecifier;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NetworkScanRequest {
     const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
 
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
index e08d63e..6d83f74 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.CellInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NetworkScanResult {
     /**
      * The result contains a part of the scan results.
diff --git a/radio/aidl/android/hardware/radio/network/NgranBands.aidl b/radio/aidl/android/hardware/radio/network/NgranBands.aidl
index a1c2957..53c7a3d 100644
--- a/radio/aidl/android/hardware/radio/network/NgranBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/NgranBands.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum NgranBands {
     /**
      * 3GPP TS 38.101-1, Table 5.2-1: FR1 bands
diff --git a/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl b/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl
index e40d4f9..e293dff 100644
--- a/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="byte")
+@JavaDerive(toString=true)
 enum NrDualConnectivityState {
     /**
      * Enable NR dual connectivity. Enabled state does not mean dual connectivity is active.
diff --git a/radio/aidl/android/hardware/radio/network/NrIndicators.aidl b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
index 98fac25..32cc964 100644
--- a/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
@@ -20,6 +20,7 @@
  * The parameters of NR 5G Non-Standalone.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NrIndicators {
     /**
      * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
diff --git a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
index d2ac02b..1bb569a 100644
--- a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NrSignalStrength {
     /**
      * SS reference signal received power, multiplied by -1.
diff --git a/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
index bae5f40..197f401 100644
--- a/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
@@ -21,6 +21,7 @@
  * normal voice calls.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable NrVopsInfo {
     /**
      * Emergency services not supported
diff --git a/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
index 9fa126d..56f4dca 100644
--- a/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable OperatorInfo {
     const int STATUS_UNKNOWN = 0;
     const int STATUS_AVAILABLE = 1;
diff --git a/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl b/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl
index bf3f75a..23ae3b1 100644
--- a/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl
+++ b/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum PhoneRestrictedState {
     /**
      * No restriction at all including voice/SMS/USSD/SS/AV64 and packet data.
diff --git a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
index b6072ba..9996953 100644
--- a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
+++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.network.PhysicalChannelConfigBand;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PhysicalChannelConfig {
     /**
      * Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING
diff --git a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
index f5b248e..707a032 100644
--- a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
+++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
@@ -22,6 +22,7 @@
 import android.hardware.radio.network.UtranBands;
 
 @VintfStability
+@JavaDerive(toString=true)
 union PhysicalChannelConfigBand {
     boolean noinit;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
index dcc9d53..8504248 100644
--- a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
+++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.network.RadioAccessSpecifierBands;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RadioAccessSpecifier {
     /**
      * The type of network to scan.
diff --git a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
index c72d8c9..38afee5 100644
--- a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
@@ -22,6 +22,7 @@
 import android.hardware.radio.network.UtranBands;
 
 @VintfStability
+@JavaDerive(toString=true)
 union RadioAccessSpecifierBands {
     boolean noinit;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl b/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl
index 4fdc614..45c4a51 100644
--- a/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl
+++ b/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RadioBandMode {
     /**
      * "Unspecified" (selected by baseband automatically)
diff --git a/radio/aidl/android/hardware/radio/network/RegState.aidl b/radio/aidl/android/hardware/radio/network/RegState.aidl
index bb2c3c3..3f13783 100644
--- a/radio/aidl/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegState.aidl
@@ -23,6 +23,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RegState {
     /**
      * Not registered, MT is not currently searching for a new operator to register
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index 312182e..3d96b8c 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -23,6 +23,7 @@
 import android.hardware.radio.network.RegistrationFailCause;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable RegStateResult {
     /**
      * Registration state. If the RAT is indicated as a GERAN, UTRAN, or CDMA2000 technology, this
diff --git a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
index 586436e..9549f2e 100644
--- a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum RegistrationFailCause {
     /**
      * 0 - None
diff --git a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
index 5a18b18..ddb4582 100644
--- a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
@@ -25,6 +25,7 @@
 import android.hardware.radio.network.WcdmaSignalStrength;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SignalStrength {
     /**
      * If GSM measurements are provided, this structure must contain valid measurements; otherwise
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 584ea38..2f90180 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -22,6 +22,7 @@
  * Contains the threshold values of each signal measurement type.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SignalThresholdInfo {
     /**
      * Received Signal Strength Indication.
diff --git a/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
index dce437a..d4229e1 100644
--- a/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
+++ b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SuppSvcNotification {
     /**
      * Notification type
diff --git a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
index 13f394a..ec9ca6b 100644
--- a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable TdscdmaSignalStrength {
     /**
      * UTRA carrier RSSI as defined in TS 25.225 5.1.4. Valid values are (0-31, 99) as defined in
diff --git a/radio/aidl/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
index ba8fe93..5a714a4 100644
--- a/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
+++ b/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
@@ -24,6 +24,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum UsageSetting {
     /**
      * UE operates in voice-centric mode. Generally speaking, in this mode of operation, the UE
diff --git a/radio/aidl/android/hardware/radio/network/UtranBands.aidl b/radio/aidl/android/hardware/radio/network/UtranBands.aidl
index da21f9b..a0fd427 100644
--- a/radio/aidl/android/hardware/radio/network/UtranBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/UtranBands.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum UtranBands {
     BAND_1 = 1,
     BAND_2 = 2,
diff --git a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
index 21021e5..7595c05 100644
--- a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.network;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable WcdmaSignalStrength {
     /**
      * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means unreported.
diff --git a/radio/aidl/android/hardware/radio/sim/AppStatus.aidl b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
index 07939bb..c072f6a 100644
--- a/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.sim.PinState;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable AppStatus {
     const int APP_STATE_UNKNOWN = 0;
     const int APP_STATE_DETECTED = 1;
diff --git a/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl b/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl
index b69296d..f8b5922 100644
--- a/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum CardPowerState {
     POWER_DOWN,
     POWER_UP,
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index 3098c4d..a14cf7d 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.sim.PinState;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CardStatus {
     /*
      * Card is physically absent from device. (Some old modems use STATE_ABSENT when the SIM
diff --git a/radio/aidl/android/hardware/radio/sim/Carrier.aidl b/radio/aidl/android/hardware/radio/sim/Carrier.aidl
index c870c00..d25214f 100644
--- a/radio/aidl/android/hardware/radio/sim/Carrier.aidl
+++ b/radio/aidl/android/hardware/radio/sim/Carrier.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable Carrier {
     /**
      * Apply to all carrier with the same mcc/mnc
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index ef38fdc..3dce907 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.sim.Carrier;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CarrierRestrictions {
     /**
      * Allowed carriers
diff --git a/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index bdd7e07..6aa6926 100644
--- a/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum CdmaSubscriptionSource {
     RUIM_SIM,
     NV,
diff --git a/radio/aidl/android/hardware/radio/sim/IccIo.aidl b/radio/aidl/android/hardware/radio/sim/IccIo.aidl
index be5e832..f173c8e 100644
--- a/radio/aidl/android/hardware/radio/sim/IccIo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IccIo.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable IccIo {
     /**
      * One of the commands listed for TS 27.007 +CRSM
diff --git a/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
index 8aa9e8f..efcbbda 100644
--- a/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable IccIoResult {
     int sw1;
     int sw2;
diff --git a/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
index e8b3807..ba1dda5 100644
--- a/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
@@ -20,6 +20,7 @@
  * Carrier specific Information sent by the carrier, which will be used to encrypt IMSI and IMPI.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable ImsiEncryptionInfo {
     /**
      * Key type to be used for ePDG
diff --git a/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl b/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl
index 953335b..b1385a4 100644
--- a/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="byte")
+@JavaDerive(toString=true)
 enum PbReceivedStatus {
     /**
      * Indicates that retrieval is fine.
diff --git a/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl b/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl
index f01ff61..f85c84b 100644
--- a/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum PersoSubstate {
     /**
      * Initial state
diff --git a/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
index 23a0208..97c3dba 100644
--- a/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PhonebookCapacity {
     /**
      * Maximum number of ADN records possible in the SIM phonebook. Needs to be non-negative.
diff --git a/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
index 03326b8..c4db0e6 100644
--- a/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
@@ -21,6 +21,7 @@
  * as per 3GPP spec 31.102 v15 Section-4.4.2.3.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable PhonebookRecordInfo {
     /**
      * Record index. 0 is used to insert a record
diff --git a/radio/aidl/android/hardware/radio/sim/PinState.aidl b/radio/aidl/android/hardware/radio/sim/PinState.aidl
index 03b8e4e..85048bb 100644
--- a/radio/aidl/android/hardware/radio/sim/PinState.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PinState.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum PinState {
     UNKNOWN,
     ENABLED_NOT_VERIFIED,
diff --git a/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
index 3c152d6..553404b 100644
--- a/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SelectUiccSub {
     const int SUBSCRIPTION_TYPE_1 = 0;
     const int SUBSCRIPTION_TYPE_2 = 1;
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index 1dc707e..43adbbc 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SimApdu {
     /**
      * "sessionid" from TS 27.007 +CGLA command. Must be ignored for +CSIM command.
diff --git a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 6c03122..6490d51 100644
--- a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum SimLockMultiSimPolicy {
     /**
      * Indicates that configuration applies to each slot independently.
diff --git a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
index 483a54c..69aff66 100644
--- a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.sim;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SimRefreshResult {
     /**
      * A file on SIM has been updated.
diff --git a/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl b/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl
index 94d5f88..dc47172 100644
--- a/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl
+++ b/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum AudioQuality {
     /**
      * Unspecified audio codec
diff --git a/radio/aidl/android/hardware/radio/voice/Call.aidl b/radio/aidl/android/hardware/radio/voice/Call.aidl
index beb079b..b09d7a0 100644
--- a/radio/aidl/android/hardware/radio/voice/Call.aidl
+++ b/radio/aidl/android/hardware/radio/voice/Call.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.voice.UusInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable Call {
     const int PRESENTATION_ALLOWED = 0;
     const int PRESENTATION_RESTRICTED = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
index b7ddcd9..c4143b9 100644
--- a/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
@@ -20,6 +20,7 @@
  * See also com.android.internal.telephony.gsm.CallForwardInfo
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CallForwardInfo {
     const int STATUS_DISABLE = 0;
     const int STATUS_ENABLE = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
index 7ba6a72..4d447d7 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.voice.CdmaSignalInfoRecord;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaCallWaiting {
     const int NUMBER_PLAN_UNKNOWN = 0;
     const int NUMBER_PLAN_ISDN = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index ac66237..522f7ae 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -24,6 +24,7 @@
  * a byte buffer. The display_tag, display_len and chari fields are all 1 byte.
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaDisplayInfoRecord {
     const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 6920462..1a4f1b3 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -28,6 +28,7 @@
 /**
  * Max length of CdmaInformationRecords[] is CDMA_MAX_NUMBER_OF_INFO_RECS
  */
+@JavaDerive(toString=true)
 parcelable CdmaInformationRecord {
     const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
index c3bda23..8bfc5f7 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -20,6 +20,7 @@
  * Line Control Information Record as defined in C.S0005 section 3.7.5.15
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaLineControlInfoRecord {
     byte lineCtrlPolarityIncluded;
     byte lineCtrlToggle;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index 265bf67..9084b25 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -22,6 +22,7 @@
  * Connected Number Info Rec as defined in C.S0005 section 3.7.5.4
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaNumberInfoRecord {
     const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index 7b4205a..81fb003 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum CdmaOtaProvisionStatus {
     SPL_UNLOCKED,
     SPC_RETRIES_EXCEEDED,
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
index f3bcc0f..5c9e2f2 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.voice.CdmaNumberInfoRecord;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaRedirectingNumberInfoRecord {
     /**
      * Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
index 5fc8776..3334475 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -20,6 +20,7 @@
  * CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaSignalInfoRecord {
     /**
      * True if signal information record is present
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
index c41f8e3..9795cf0 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -20,6 +20,7 @@
  * T53 Audio Control Information Record
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaT53AudioControlInfoRecord {
     byte upLink;
     byte downLink;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
index e37a072..5ccd251 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -20,6 +20,7 @@
  * T53 CLIR Information Record
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CdmaT53ClirInfoRecord {
     byte cause;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CfData.aidl b/radio/aidl/android/hardware/radio/voice/CfData.aidl
index f28c7c8..8f4c227 100644
--- a/radio/aidl/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CfData.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.voice.CallForwardInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CfData {
     const int NUM_SERVICE_CLASSES = 7;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl b/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl
index 4b10ecc..4021471 100644
--- a/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl
+++ b/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum ClipStatus {
     /**
      * CLIP provisioned
diff --git a/radio/aidl/android/hardware/radio/voice/Dial.aidl b/radio/aidl/android/hardware/radio/voice/Dial.aidl
index 7d61fe5..ca028ad 100644
--- a/radio/aidl/android/hardware/radio/voice/Dial.aidl
+++ b/radio/aidl/android/hardware/radio/voice/Dial.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.voice.UusInfo;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable Dial {
     /**
      * Use subscription default value
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl
index 75a41c9..d623346 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum EmergencyCallRouting {
     /**
      * Indicates Android does not require how to handle the corresponding emergency call; it is
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index 9fed78e..e380ce8 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -39,6 +39,7 @@
  *            RFC 5031
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable EmergencyNumber {
     /**
      * Indicates the number is from the network signal.
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl
index cfebc47..a4ac7aa 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl
@@ -34,6 +34,7 @@
  */
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum EmergencyServiceCategory {
     /**
      * General emergency call, all categories
diff --git a/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
index 5e328d4..5c8c819 100644
--- a/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum LastCallFailCause {
     UNOBTAINABLE_NUMBER = 1,
     NO_ROUTE_TO_DESTINATION = 3,
diff --git a/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
index 084bedd..078722a 100644
--- a/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
@@ -19,6 +19,7 @@
 import android.hardware.radio.voice.LastCallFailCause;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable LastCallFailCauseInfo {
     LastCallFailCause causeCode;
     String vendorCause;
diff --git a/radio/aidl/android/hardware/radio/voice/SrvccState.aidl b/radio/aidl/android/hardware/radio/voice/SrvccState.aidl
index ddf75db..08eb877 100644
--- a/radio/aidl/android/hardware/radio/voice/SrvccState.aidl
+++ b/radio/aidl/android/hardware/radio/voice/SrvccState.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum SrvccState {
     HANDOVER_STARTED,
     HANDOVER_COMPLETED,
diff --git a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
index d562925..b944bf4 100644
--- a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.voice;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable SsInfoData {
     const int SS_INFO_MAX = 4;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index be1b611..7982275 100644
--- a/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.voice.SsInfoData;
 
 @VintfStability
+@JavaDerive(toString=true)
 parcelable StkCcUnsolSsResult {
     const int REQUEST_TYPE_ACTIVATION = 0;
     const int REQUEST_TYPE_DEACTIVATION = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/TtyMode.aidl b/radio/aidl/android/hardware/radio/voice/TtyMode.aidl
index 81a846b..e8dd723 100644
--- a/radio/aidl/android/hardware/radio/voice/TtyMode.aidl
+++ b/radio/aidl/android/hardware/radio/voice/TtyMode.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum TtyMode {
     OFF,
     FULL,
diff --git a/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
index 48d1fca..cece4bd 100644
--- a/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
+++ b/radio/aidl/android/hardware/radio/voice/UssdModeType.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @Backing(type="int")
+@JavaDerive(toString=true)
 enum UssdModeType {
     /**
      * USSD-Notify
diff --git a/radio/aidl/android/hardware/radio/voice/UusInfo.aidl b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
index 19e73f7..220a8fc 100644
--- a/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
@@ -20,6 +20,7 @@
  * User-to-User Signaling Information defined in 3GPP 23.087 v8.0
  */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable UusInfo {
     /**
      * User specified protocol
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
index 76f15bf..efc4f26 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.cpp
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -24,6 +24,7 @@
 #define WAIT_TIMEOUT_PERIOD 75
 
 sim::CardStatus cardStatus = {};
+config::SimSlotStatus slotStatus = {};
 int serial = 0;
 int count_ = 0;
 
@@ -204,3 +205,21 @@
     EXPECT_EQ(serial, radioSimRsp->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioSimRsp->rspInfo.error);
 }
+
+void RadioServiceTest::updateSimSlotStatus(int physicalSlotId) {
+    // Update SimSlotStatus from RadioConfig
+    std::shared_ptr<RadioConfigResponse> radioConfigRsp =
+            ndk::SharedRefBase::make<RadioConfigResponse>(*this);
+    std::shared_ptr<RadioConfigIndication> radioConfigInd =
+            ndk::SharedRefBase::make<RadioConfigIndication>(*this);
+    radio_config->setResponseFunctions(radioConfigRsp, radioConfigInd);
+    serial = GetRandomSerialNumber();
+    radio_config->getSimSlotsStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioConfigRsp->rspInfo.type);
+    EXPECT_EQ(serial, radioConfigRsp->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioConfigRsp->rspInfo.error);
+    if (radioConfigRsp->simSlotStatus.size() > physicalSlotId) {
+        slotStatus = radioConfigRsp->simSlotStatus[physicalSlotId];
+    }
+}
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
index 414ffbc..47976b9 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.h
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -20,6 +20,7 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/radio/RadioError.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/config/SimSlotStatus.h>
 #include <aidl/android/hardware/radio/network/RegState.h>
 #include <aidl/android/hardware/radio/sim/CardStatus.h>
 #include <aidl/android/hardware/radio/sim/IRadioSim.h>
@@ -27,10 +28,12 @@
 #include <vector>
 
 using namespace aidl::android::hardware::radio;
+using aidl::android::hardware::radio::config::SimSlotStatus;
 using aidl::android::hardware::radio::network::RegState;
 using aidl::android::hardware::radio::sim::CardStatus;
 
 extern CardStatus cardStatus;
+extern SimSlotStatus slotStatus;
 extern int serial;
 extern int count_;
 
@@ -67,6 +70,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 MODEM_SET_SIM_SLOT_MAPPING_DELAY_IN_SECONDS 6
 
 #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
@@ -141,4 +145,7 @@
 
     /* Update SIM card status */
     void updateSimCardStatus();
+
+    /* Update SIM slot status */
+    void updateSimSlotStatus(int physicalSlotId);
 };
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index 8d81605..7384f87 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -19,8 +19,9 @@
 RadioConfigResponse::RadioConfigResponse(RadioServiceTest& parent) : parent_config(parent) {}
 
 ndk::ScopedAStatus RadioConfigResponse::getSimSlotsStatusResponse(
-        const RadioResponseInfo& info, const std::vector<SimSlotStatus>& /* slotStatus */) {
+        const RadioResponseInfo& info, const std::vector<SimSlotStatus>& slotStatus) {
     rspInfo = info;
+    simSlotStatus = slotStatus;
     parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index 43b63e8..258b172 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -39,6 +39,19 @@
     radio_config->setResponseFunctions(radioRsp_config, radioInd_config);
 }
 
+void RadioConfigTest::updateSimSlotStatus() {
+    serial = GetRandomSerialNumber();
+    radio_config->getSimSlotsStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_config->rspInfo.error);
+    // assuming only 1 slot
+    for (const SimSlotStatus& slotStatusResponse : radioRsp_config->simSlotStatus) {
+        slotStatus = slotStatusResponse;
+    }
+}
+
 /*
  * Test IRadioConfig.getHalDeviceCapabilities() for the response returned.
  */
@@ -46,6 +59,7 @@
     serial = GetRandomSerialNumber();
     ndk::ScopedAStatus res = radio_config->getHalDeviceCapabilities(serial);
     ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
     ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
           toString(radioRsp_config->rspInfo.error).c_str());
 }
@@ -57,6 +71,7 @@
     serial = GetRandomSerialNumber();
     ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
     ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
     ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
           toString(radioRsp_config->rspInfo.error).c_str());
 }
@@ -148,3 +163,99 @@
                                  {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE,
                                   RadioError::INTERNAL_ERR}));
 }
+
+/*
+ * Test IRadioConfig.setSimSlotsMapping() for the response returned.
+ */
+TEST_P(RadioConfigTest, setSimSlotsMapping) {
+    // get slot status and set SIM slots mapping based on the result.
+    updateSimSlotStatus();
+    if (radioRsp_config->rspInfo.error == RadioError::NONE) {
+        SlotPortMapping slotPortMapping;
+        // put invalid value at first and adjust by slotStatusResponse.
+        slotPortMapping.physicalSlotId = -1;
+        slotPortMapping.portId = -1;
+        std::vector<SlotPortMapping> slotPortMappingList = {slotPortMapping};
+        if (isDsDsEnabled()) {
+            slotPortMappingList.push_back(slotPortMapping);
+        } else if (isTsTsEnabled()) {
+            slotPortMappingList.push_back(slotPortMapping);
+            slotPortMappingList.push_back(slotPortMapping);
+        }
+        for (size_t i = 0; i < radioRsp_config->simSlotStatus.size(); i++) {
+            ASSERT_TRUE(radioRsp_config->simSlotStatus[i].portInfo.size() > 0);
+            for (size_t j = 0; j < radioRsp_config->simSlotStatus[i].portInfo.size(); j++) {
+                if (radioRsp_config->simSlotStatus[i].portInfo[j].portActive) {
+                    int32_t logicalSlotId =
+                            radioRsp_config->simSlotStatus[i].portInfo[j].logicalSlotId;
+                    // logicalSlotId should be 0 or positive numbers if the port
+                    // is active.
+                    EXPECT_GE(logicalSlotId, 0);
+                    // logicalSlotId should be less than the maximum number of
+                    // supported SIM slots.
+                    EXPECT_LT(logicalSlotId, slotPortMappingList.size());
+                    if (logicalSlotId >= 0 && logicalSlotId < slotPortMappingList.size()) {
+                        slotPortMappingList[logicalSlotId].physicalSlotId = i;
+                        slotPortMappingList[logicalSlotId].portId = j;
+                    }
+                }
+            }
+        }
+
+        // set SIM slots mapping
+        for (size_t i = 0; i < slotPortMappingList.size(); i++) {
+            // physicalSlotId and portId should be 0 or positive numbers for the
+            // input of setSimSlotsMapping.
+            EXPECT_GE(slotPortMappingList[i].physicalSlotId, 0);
+            EXPECT_GE(slotPortMappingList[i].portId, 0);
+        }
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_config->setSimSlotsMapping(serial, slotPortMappingList);
+        ASSERT_OK(res);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+        ALOGI("setSimSlotsMapping, rspInfo.error = %s\n",
+              toString(radioRsp_config->rspInfo.error).c_str());
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error, {RadioError::NONE}));
+
+        // Give some time for modem to fully switch SIM configuration
+        sleep(MODEM_SET_SIM_SLOT_MAPPING_DELAY_IN_SECONDS);
+    }
+}
+
+/*
+ * Test IRadioConfig.getSimSlotStatus() for the response returned.
+ */
+
+TEST_P(RadioConfigTest, checkPortInfoExistsAndPortActive) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
+    ASSERT_OK(res);
+    ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+    if (radioRsp_config->rspInfo.error == RadioError::NONE) {
+        uint8_t simCount = 0;
+        // check if cardState is present, portInfo size should be more than 0
+        for (const SimSlotStatus& slotStatusResponse : radioRsp_config->simSlotStatus) {
+            if (slotStatusResponse.cardState == CardStatus::STATE_PRESENT) {
+                ASSERT_TRUE(slotStatusResponse.portInfo.size() > 0);
+                for (const SimPortInfo& simPortInfo : slotStatusResponse.portInfo) {
+                    if (simPortInfo.portActive) {
+                        simCount++;
+                    }
+                }
+            }
+        }
+        if (isSsSsEnabled()) {
+            EXPECT_EQ(1, simCount);
+        } else if (isDsDsEnabled()) {
+            EXPECT_EQ(2, simCount);
+        } else if (isTsTsEnabled()) {
+            EXPECT_EQ(3, simCount);
+        }
+    }
+}
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
index 465c106..3db430d 100644
--- a/radio/aidl/vts/radio_config_utils.h
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -38,6 +38,7 @@
     RadioResponseInfo rspInfo;
     PhoneCapability phoneCap;
     bool modemReducedFeatureSet1;
+    std::vector<SimSlotStatus> simSlotStatus;
 
     virtual ndk::ScopedAStatus getSimSlotsStatusResponse(
             const RadioResponseInfo& info, const std::vector<SimSlotStatus>& slotStatus) override;
@@ -77,6 +78,8 @@
   public:
     virtual void SetUp() override;
     ndk::ScopedAStatus updateSimCardStatus();
+    /* Override updateSimSlotStatus in RadioServiceTest to not call setResponseFunctions */
+    void updateSimSlotStatus();
 
     /* radio config service handle in RadioServiceTest */
     /* radio config response handle */
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index d2715a8..20b44c5 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -24,6 +24,7 @@
 
 ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& info) {
     rspInfo = info;
+    enableModemResponseToggle = !enableModemResponseToggle;
     parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index 8779e0c..49e1891 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -37,7 +37,7 @@
 
     RadioResponseInfo rspInfo;
     bool isModemEnabled;
-    bool enableModemResponseToggle;
+    bool enableModemResponseToggle = false;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index e1d508d..0bae374 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -592,6 +592,89 @@
 }
 
 /*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for multi-RANs per request
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_multiRansPerRequest) {
+    SignalThresholdInfo signalThresholdInfoGeran;
+    signalThresholdInfoGeran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfoGeran.hysteresisMs = 5000;
+    signalThresholdInfoGeran.hysteresisDb = 2;
+    signalThresholdInfoGeran.thresholds = {-109, -103, -97, -89};
+    signalThresholdInfoGeran.isEnabled = true;
+    signalThresholdInfoGeran.ran = AccessNetwork::GERAN;
+
+    SignalThresholdInfo signalThresholdInfoUtran;
+    signalThresholdInfoUtran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSCP;
+    signalThresholdInfoUtran.hysteresisMs = 5000;
+    signalThresholdInfoUtran.hysteresisDb = 2;
+    signalThresholdInfoUtran.thresholds = {-110, -97, -73, -49, -25};
+    signalThresholdInfoUtran.isEnabled = true;
+    signalThresholdInfoUtran.ran = AccessNetwork::UTRAN;
+
+    SignalThresholdInfo signalThresholdInfoEutran;
+    signalThresholdInfoEutran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRP;
+    signalThresholdInfoEutran.hysteresisMs = 5000;
+    signalThresholdInfoEutran.hysteresisDb = 2;
+    signalThresholdInfoEutran.thresholds = {-128, -108, -88, -68};
+    signalThresholdInfoEutran.isEnabled = true;
+    signalThresholdInfoEutran.ran = AccessNetwork::EUTRAN;
+
+    SignalThresholdInfo signalThresholdInfoCdma2000;
+    signalThresholdInfoCdma2000.signalMeasurement =
+            SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfoCdma2000.hysteresisMs = 5000;
+    signalThresholdInfoCdma2000.hysteresisDb = 2;
+    signalThresholdInfoCdma2000.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfoCdma2000.isEnabled = true;
+    signalThresholdInfoCdma2000.ran = AccessNetwork::CDMA2000;
+
+    SignalThresholdInfo signalThresholdInfoNgran;
+    signalThresholdInfoNgran.signalMeasurement =
+            SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
+    signalThresholdInfoNgran.hysteresisMs = 5000;
+    signalThresholdInfoNgran.hysteresisDb = 0;
+    signalThresholdInfoNgran.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfoNgran.isEnabled = true;
+    signalThresholdInfoNgran.ran = AccessNetwork::NGRAN;
+
+    const static std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
+            signalThresholdInfoGeran, signalThresholdInfoUtran, signalThresholdInfoEutran,
+            signalThresholdInfoCdma2000, signalThresholdInfoNgran};
+
+    std::vector<SignalThresholdInfo> supportedSignalThresholdInfos;
+    for (size_t i = 0; i < candidateSignalThresholdInfos.size(); i++) {
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_network->setSignalStrengthReportingCriteria(
+                serial, {candidateSignalThresholdInfos[i]});
+        ASSERT_OK(res);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+            supportedSignalThresholdInfos.push_back(signalThresholdInfoGeran);
+        } else {
+            // Refer to IRadioNetworkResponse#setSignalStrengthReportingCriteriaResponse
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_network->rspInfo.error,
+                    {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE}));
+        }
+    }
+
+    ASSERT_FALSE(supportedSignalThresholdInfos.empty());
+
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_network->setSignalStrengthReportingCriteria(
+            serial, supportedSignalThresholdInfos);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ALOGI("setSignalStrengthReportingCriteria_multiRansPerRequest, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e82235c..e69247d 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -108,7 +108,13 @@
     // have CardStatus::STATE_PRESENT after turning the power back on
     if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
         updateSimCardStatus();
+        updateSimSlotStatus(cardStatus.slotMap.physicalSlotId);
         EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+        EXPECT_EQ(CardStatus::STATE_PRESENT, slotStatus.cardState);
+        if (CardStatus::STATE_PRESENT == slotStatus.cardState) {
+            ASSERT_TRUE(slotStatus.portInfo[0].portActive);
+            EXPECT_EQ(0, cardStatus.slotMap.portId);
+        }
     }
 }
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index da02d54..43dc84c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -196,12 +196,12 @@
  * derive a key that is used to encrypt the private/secret key material.
  *
  * The root of trust consists of a bitstring that must be derived from the public key used by
- * Verified Boot to verify the signature on the boot image and from the lock state of the
- * device.  If the public key is changed to allow a different system image to be used or if the
- * lock state is changed, then all of the IKeyMintDevice-protected keys created by the previous
- * system state must be unusable, unless the previous state is restored.  The goal is to increase
- * the value of the software-enforced key access controls by making it impossible for an attacker-
- * installed operating system to use IKeyMintDevice keys.
+ * Verified Boot to verify the signature on the boot image, from the lock state and from the
+ * Verified Boot state of the device.  If the public key is changed to allow a different system
+ * image to be used or if the lock state is changed, then all of the IKeyMintDevice-protected keys
+ * created by the previous system state must be unusable, unless the previous state is restored.
+ * The goal is to increase the value of the software-enforced key access controls by making it
+ * impossible for an attacker-installed operating system to use IKeyMintDevice keys.
  *
  * == Version Binding ==
  *
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index ca89555..c30c183 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -242,7 +242,8 @@
      *   not a multiple of the AES block size, finish() must return
      *   ErrorCode::INVALID_INPUT_LENGTH.  If padding is PaddingMode::PKCS7, pad the data per the
      *   PKCS#7 specification, including adding an additional padding block if the data is a
-     *   multiple of the block length.
+     *   multiple of the block length.  If padding is PaddingMode::PKCS7 and decryption does not
+     *   result in valid padding, return ErrorCode::INVALID_ARGUMENT.
      *
      * o BlockMode::GCM.  During encryption, after processing all plaintext, compute the tag
      *   (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext.  During decryption,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 5024400..8b3875b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -18,13 +18,20 @@
 
 /**
  * ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
- * authenticate the keysToSign (see keysToSignMac output argument).
+ * authenticate the keysToSign (see keysToSignMac output argument of
+ * IRemotelyProvisionedComponent.generateCertificateRequest).
  * @hide
  */
 @VintfStability
 parcelable ProtectedData {
     /**
-     * ProtectedData is a COSE_Encrypt structure, specified by the following CDDL
+     * ProtectedData is a COSE_Encrypt structure, encrypted with an AES key that is agreed upon
+     * using Elliptic-curve Diffie-Hellman. The contents of the structure are specified by the
+     * following CDDL [RFC8610].
+     *
+     * Notes:
+     *   - None of the CBOR in ProtectedData uses CBOR tags. If an implementation includes
+     *     tags, parsers may reject the data.
      *
      *     ProtectedData = [               // COSE_Encrypt
      *         protected: bstr .cbor {
@@ -34,13 +41,18 @@
      *             5 : bstr .size 12       // IV
      *         },
      *         ciphertext: bstr,           // AES-GCM-256(K, .cbor ProtectedDataPayload)
+     *                                     // Where the encryption key 'K' is derived as follows:
+     *                                     // ikm = ECDH(EEK_pub, Ephemeral_priv)
+     *                                     // salt = null
+     *                                     // info = .cbor Context (see below)
+     *                                     // K = HKDF-SHA-256(ikm, salt, info)
      *         recipients : [
      *             [                       // COSE_Recipient
      *                 protected : bstr .cbor {
      *                     1 : -25         // Algorithm : ECDH-ES + HKDF-256
      *                 },
      *                 unprotected : {
-     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  // Of the sender
+     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  // Ephemeral_pub
      *                     4 : bstr,       // KID : EEK ID
      *                 },
      *                 ciphertext : nil
@@ -48,14 +60,14 @@
      *         ]
      *     ]
      *
-     *     K = HKDF-256(ECDH(EEK_pub, Ephemeral_priv), Context)
-     *
-     *     Context = [                     // COSE_KDF_Context
+     *     // The COSE_KDF_Context that is used to derive the ProtectedData encryption key with
+     *     // HKDF. See details on use in ProtectedData comments above.
+     *     Context = [
      *         AlgorithmID : 3             // AES-GCM 256
      *         PartyUInfo : [
      *             identity : bstr "client"
      *             nonce : bstr .size 0,
-     *             other : bstr            // Ephemeral pubkey
+     *             other : bstr            // Ephemeral_pub
      *         ],
      *         PartyVInfo : [
      *             identity : bstr "server",
@@ -68,76 +80,106 @@
      *         ]
      *     ]
      *
+     *     // The data that is encrypted and included in ProtectedData ciphertext (see above).
      *     ProtectedDataPayload [
      *         SignedMac,
      *         Bcc,
      *         ? AdditionalDKSignatures,
      *     ]
+     *
+     *     // AdditionalDKSignatures allows the platform to provide additional certifications
+     *     // for the DK_pub. For example, this could be provided by the hardware vendor, who
+     *     // certifies all of their devices. The SignerName is a free-form string describing
+     *     // who generated the signature.
      *     AdditionalDKSignatures = {
      *         + SignerName => DKCertChain
      *     }
      *
+     *     // SignerName is a string identifier that indicates both the signing authority as
+     *     // well as the format of the DKCertChain
      *     SignerName = tstr
      *
      *     DKCertChain = [
-     *         2* Certificate                      // Root -> Leaf.  Root is the vendor
-     *                                             // self-signed cert, leaf contains DK_pub
+     *         2* X509Certificate       // Root -> ... -> Leaf. "Root" is the vendor self-signed
+     *                                  // cert, "Leaf" contains DK_pub. There may also be
+     *                                  // intermediate certificates between Root and Leaf.
      *     ]
      *
-     *     Certificate = COSE_Sign1 of a public key
+     *     // A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA)
+     *     X509Certificate = bstr
      *
-     *     SignedMac = [                                  // COSE_Sign1
-     *         bstr .cbor {                               // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256,   // Algorithm
+     *     // The SignedMac, which authenticates the MAC key that is used to authenticate the
+     *     // keysToSign.
+     *     SignedMac = [                                // COSE_Sign1
+     *         bstr .cbor {                             // Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
      *         },
-     *         {},                   // Unprotected params
-     *         bstr .size 32,                  // MAC key
+     *         {},                                      // Unprotected params
+     *         bstr .size 32,                           // Payload: MAC key
      *         bstr // PureEd25519(KM_priv, bstr .cbor SignedMac_structure) /
      *              // ECDSA(KM_priv, bstr .cbor SignedMac_structure)
      *     ]
      *
-     *     SignedMac_structure = [
+     *     SignedMac_structure = [                      //  COSE Sig_structure
      *         "Signature1",
-     *         bstr .cbor {                               // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256,   // Algorithm
+     *         bstr .cbor {                             // Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
      *         },
-     *         bstr .cbor SignedMacAad
-     *         bstr .size 32                              // MAC key
+     *         bstr .cbor SignedMacAad,
+     *         bstr .size 32                            // MAC key
      *     ]
      *
      *     SignedMacAad = [
-     *         challenge : bstr,
+     *         challenge : bstr .size (32..64),   // Size between 32 - 64
+     *                                            // bytes inclusive
      *         VerifiedDeviceInfo,
      *         tag: bstr                 // This is the tag from COSE_Mac0 of
      *                                   // KeysToCertify, to tie the key set to
      *                                   // the signature.
      *     ]
      *
+     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
+     *
+     *     // The BCC is the boot certificate chain, containing measurements about the device
+     *     // boot chain. The BCC generally follows the Open Profile for DICE specification at
+     *     // https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md.
+     *     //
+     *     // The first entry in the Bcc is the DK_pub, encoded as a COSE_key. All entries after
+     *     // the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN).
+     *     // Note that there is no BccEntry for DK_pub, only a "bare" COSE_key.
      *     Bcc = [
      *         PubKeyEd25519 / PubKeyECDSA256, // DK_pub
      *         + BccEntry,                     // Root -> leaf (KM_pub)
      *     ]
      *
-     *     BccPayload = {                     // CWT
-     *         1 : tstr,                      // Issuer
-     *         2 : tstr,                      // Subject
-     *         // See the Open Profile for DICE for details on these fields.
-     *         ? -4670545 : bstr,             // Code Hash
-     *         ? -4670546 : bstr,             // Code Descriptor
-     *         ? -4670547 : bstr,             // Configuration Hash
-     *         ? -4670548 : bstr .cbor {      // Configuration Descriptor
-     *             ? -70002 : tstr,           // Component name
-     *             ? -70003 : int,            // Firmware version
-     *             ? -70004 : null,           // Resettable
-     *         },
-     *         ? -4670549 : bstr,             // Authority Hash
-     *         ? -4670550 : bstr,             // Authority Descriptor
-     *         ? -4670551 : bstr,             // Mode
+     *     // This is the signed payload for each entry in the Bcc. Note that the "Configuration
+     *     // Input Values" described by the Open Profile are not used here. Instead, the Bcc
+     *     // defines its own configuration values for the Configuration Descriptor field. See
+     *     // the Open Profile for DICE for more details on the fields. All hashes are SHA256.
+     *     BccPayload = {                               // CWT [RFC8392]
+     *         1 : tstr,                                // Issuer
+     *         2 : tstr,                                // Subject
      *         -4670552 : bstr .cbor PubKeyEd25519 /
-     *                    bstr .cbor PubKeyECDSA256   // Subject Public Key
-     *         -4670553 : bstr                // Key Usage
+     *                    bstr .cbor PubKeyECDSA256,    // Subject Public Key
+     *         -4670553 : bstr                          // Key Usage
+     *
+     *         // NOTE: All of the following fields may be omitted for a "Degenerate BCC", as
+     *         //       described by IRemotelyProvisionedComponent.aidl.
+     *         -4670545 : bstr,                         // Code Hash
+     *         ? -4670546 : bstr,                       // Code Descriptor
+     *         ? -4670547 : bstr,                       // Configuration Hash
+     *         -4670548 : bstr .cbor {                  // Configuration Descriptor
+     *             ? -70002 : tstr,                         // Component name
+     *             ? -70003 : int,                          // Firmware version
+     *             ? -70004 : null,                         // Resettable
+     *         },
+     *         -4670549 : bstr,                         // Authority Hash
+     *         ? -4670550 : bstr,                       // Authority Descriptor
+     *         -4670551 : bstr,                         // Mode
      *     }
      *
+     *     // Each entry in the Bcc is a BccPayload signed by the key from the previous entry
+     *     // in the Bcc array.
      *     BccEntry = [                                  // COSE_Sign1 (untagged)
      *         protected : bstr .cbor {
      *             1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
@@ -158,8 +200,8 @@
      *         payload: bstr .cbor BccPayload
      *     ]
      *
-     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
-     *
+     *     // The following section defines some types that are reused throughout the above
+     *     // data structures.
      *     PubKeyX25519 = {                 // COSE_Key
      *          1 : 1,                      // Key type : Octet Key Pair
      *         -1 : 4,                      // Curve : X25519
@@ -167,25 +209,25 @@
      *     }
      *
      *     PubKeyEd25519 = {                // COSE_Key
-     *         1 : 1,                         // Key type : octet key pair
-     *         3 : AlgorithmEdDSA,            // Algorithm : EdDSA
-     *         -1 : 6,                        // Curve : Ed25519
-     *         -2 : bstr                      // X coordinate, little-endian
+     *         1 : 1,                       // Key type : octet key pair
+     *         3 : AlgorithmEdDSA,          // Algorithm : EdDSA
+     *         -1 : 6,                      // Curve : Ed25519
+     *         -2 : bstr                    // X coordinate, little-endian
      *     }
      *
-     *     PubKeyEcdhP256 = {              // COSE_Key
-     *          1 : 2,      // Key type : EC2
-     *          -1 : 1,     // Curve : P256
-     *          -2 : bstr   // Sender X coordinate
-     *          -3 : bstr   // Sender Y coordinate
+     *     PubKeyEcdhP256 = {               // COSE_Key
+     *          1 : 2,                      // Key type : EC2
+     *          -1 : 1,                     // Curve : P256
+     *          -2 : bstr                   // Sender X coordinate
+     *          -3 : bstr                   // Sender Y coordinate
      *     }
      *
-     *     PubKeyECDSA256 = {                 // COSE_Key
-     *         1 : 2,                         // Key type : EC2
-     *         3 : AlgorithmES256,            // Algorithm : ECDSA w/ SHA-256
-     *         -1 : 1,                        // Curve: P256
-     *         -2 : bstr,                     // X coordinate
-     *         -3 : bstr                      // Y coordinate
+     *     PubKeyECDSA256 = {               // COSE_Key
+     *         1 : 2,                       // Key type : EC2
+     *         3 : AlgorithmES256,          // Algorithm : ECDSA w/ SHA-256
+     *         -1 : 1,                      // Curve: P256
+     *         -2 : bstr,                   // X coordinate
+     *         -3 : bstr                    // Y coordinate
      *     }
      *
      *     AlgorithmES256 = -7
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index b28ebcb..42dfad5 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -504,7 +504,9 @@
      * that is necessary during all uses of the key.  In particular, calls to exportKey() and
      * getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
      * begin() must provide this tag and the same associated data as part of the inParams set.  If
-     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note
+     * that a key with a zero-length APPLICATION_ID cannot have its key characteristics retrieved
+     * using getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
@@ -525,7 +527,9 @@
      * that is necessary during all uses of the key.  In particular, calls to begin() and
      * exportKey() must provide the same value to the appData parameter, and calls to begin must
      * provide this tag and the same associated data as part of the inParams set.  If the correct
-     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note that a key
+     * with a zero-length APPLICATION_DATA cannot have its key characteristics retrieved using
+     * getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 0bab54c..240de35 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -743,6 +743,11 @@
 }
 
 TEST_P(AttestKeyTest, EcdsaAttestationID) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
     // Create attestation key.
     AttestationKey attest_key;
     vector<KeyCharacteristics> attest_key_characteristics;
@@ -783,7 +788,7 @@
         vector<Certificate> attested_key_cert_chain;
         auto result = GenerateKey(builder, attest_key, &attested_key_blob,
                                   &attested_key_characteristics, &attested_key_cert_chain);
-        if (result == ErrorCode::CANNOT_ATTEST_IDS) {
+        if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
             continue;
         }
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index f9510d3..be21994 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -17,6 +17,7 @@
 #include "KeyMintAidlTestBase.h"
 
 #include <chrono>
+#include <fstream>
 #include <unordered_set>
 #include <vector>
 
@@ -207,6 +208,14 @@
     return boot_patch_level(key_characteristics_);
 }
 
+/**
+ * An API to determine device IDs attestation is required or not,
+ * which is mandatory for KeyMint version 2 or first_api_level 33 or greater.
+ */
+bool KeyMintAidlTestBase::isDeviceIdAttestationRequired() {
+    return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= 33;
+}
+
 bool KeyMintAidlTestBase::Curve25519Supported() {
     // Strongbox never supports curve 25519.
     if (SecLevel() == SecurityLevel::STRONGBOX) {
@@ -1452,6 +1461,11 @@
     OPENSSL_free(cert_issuer);
 }
 
+bool is_gsi_image() {
+    std::ifstream ifs("/system/system_ext/etc/init/init.gsi.rc");
+    return ifs.good();
+}
+
 vector<uint8_t> build_serial_blob(const uint64_t serial_int) {
     BIGNUM_Ptr serial(BN_new());
     EXPECT_TRUE(BN_set_u64(serial.get(), serial_int));
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 602dcaf..2634ab7 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -79,6 +79,7 @@
     uint32_t vendor_patch_level() { return vendor_patch_level_; }
     uint32_t boot_patch_level(const vector<KeyCharacteristics>& key_characteristics);
     uint32_t boot_patch_level();
+    bool isDeviceIdAttestationRequired();
 
     bool Curve25519Supported();
 
@@ -353,6 +354,9 @@
     }
 }
 
+// Indicate whether the test is running on a GSI image.
+bool is_gsi_image();
+
 vector<uint8_t> build_serial_blob(const uint64_t serial_int);
 void verify_subject(const X509* cert, const string& subject, bool self_signed);
 void verify_serial(X509* cert, const uint64_t expected_serial);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index f5239ed..00f72fb 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1949,6 +1949,11 @@
  * attestation extension.
  */
 TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
     auto challenge = "hello";
     auto app_id = "foo";
     auto subject = "cert subj 2";
@@ -1986,8 +1991,8 @@
         if (SecLevel() == SecurityLevel::STRONGBOX) {
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
         }
-        if (result == ErrorCode::CANNOT_ATTEST_IDS) {
-            // Device ID attestation is optional; KeyMint may not support it at all.
+        if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+            // ID attestation was optional till api level 32, from api level 33 it is mandatory.
             continue;
         }
         ASSERT_EQ(result, ErrorCode::OK);
@@ -5504,18 +5509,45 @@
 
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
         string plaintext;
-        ErrorCode error = Finish(message, &plaintext);
-        if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+        ErrorCode error = Finish(ciphertext, &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);
+            ASSERT_EQ(error, ErrorCode::OK)
+                    << "Expected INVALID_ARGUMENT or (rarely) OK, got " << error;
         }
     }
     FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
 }
 
+/*
+ * EncryptionOperationsTest.AesEcbPkcs7CiphertextTooShort
+ *
+ * Verifies that AES decryption fails in the correct way when the padding is corrupted.
+ */
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7CiphertextTooShort) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .Authorization(TAG_BLOCK_MODE, BlockMode::ECB)
+                                                 .Padding(PaddingMode::PKCS7)));
+
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+
+    string message = "a";
+    string ciphertext = EncryptMessage(message, params);
+    EXPECT_EQ(16U, ciphertext.size());
+    EXPECT_NE(ciphertext, message);
+
+    // Shorten the ciphertext.
+    ciphertext.resize(ciphertext.size() - 1);
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    string plaintext;
+    EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(ciphertext, &plaintext));
+}
+
 vector<uint8_t> CopyIv(const AuthorizationSet& set) {
     auto iv = set.GetTagValue(TAG_NONCE);
     EXPECT_TRUE(iv);
@@ -7473,7 +7505,6 @@
             uint8_t privKeyData[32];
             uint8_t pubKeyData[32];
             X25519_keypair(pubKeyData, privKeyData);
-            *localPublicKey = vector<uint8_t>(pubKeyData, pubKeyData + 32);
             *localPrivKey = EVP_PKEY_Ptr(EVP_PKEY_new_raw_private_key(
                     EVP_PKEY_X25519, nullptr, privKeyData, sizeof(privKeyData)));
         } else {
@@ -7485,16 +7516,15 @@
             ASSERT_EQ(EC_KEY_generate_key(ecKey.get()), 1);
             *localPrivKey = EVP_PKEY_Ptr(EVP_PKEY_new());
             ASSERT_EQ(EVP_PKEY_set1_EC_KEY(localPrivKey->get(), ecKey.get()), 1);
-
-            // Get encoded form of the public part of the locally generated key...
-            unsigned char* p = nullptr;
-            int localPublicKeySize = i2d_PUBKEY(localPrivKey->get(), &p);
-            ASSERT_GT(localPublicKeySize, 0);
-            *localPublicKey =
-                    vector<uint8_t>(reinterpret_cast<const uint8_t*>(p),
-                                    reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
-            OPENSSL_free(p);
         }
+
+        // Get encoded form of the public part of the locally generated key...
+        unsigned char* p = nullptr;
+        int localPublicKeySize = i2d_PUBKEY(localPrivKey->get(), &p);
+        ASSERT_GT(localPublicKeySize, 0);
+        *localPublicKey = vector<uint8_t>(reinterpret_cast<const uint8_t*>(p),
+                                          reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
+        OPENSSL_free(p);
     }
 
     void GenerateKeyMintEcKey(EcCurve curve, EVP_PKEY_Ptr* kmPubKey) {
@@ -7589,6 +7619,9 @@
     //
     for (auto curve : ValidCurves()) {
         for (auto localCurve : ValidCurves()) {
+            SCOPED_TRACE(testing::Message()
+                         << "local-curve-" << localCurve << "-keymint-curve-" << curve);
+
             // Generate EC key locally (with access to private key material)
             EVP_PKEY_Ptr localPrivKey;
             vector<uint8_t> localPublicKey;
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index 6f13867..e630f70 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -57,6 +57,15 @@
         }
     }
 
+    int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
+        int32_t version = 0;
+        auto status = keymint->getInterfaceVersion(&version);
+        if (!status.isOk()) {
+            ADD_FAILURE() << "Failed to determine interface version";
+        }
+        return version;
+    }
+
     static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
 };
 
@@ -73,12 +82,14 @@
 }
 
 TEST_F(SecureElementProvisioningTest, TeeOnly) {
-    if (keymints_.empty()) {
-        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
     }
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
+    // Execute the test only for KeyMint version >= 2.
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -111,12 +122,14 @@
 }
 
 TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
-    if (keymints_.empty()) {
-        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
     }
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
+    // Execute the test only for KeyMint version >= 2.
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = tee->getRootOfTrustChallenge(&challenge);
@@ -135,9 +148,11 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
 
     vector<uint8_t> rootOfTrust;
     Status result = sb->getRootOfTrust({}, &rootOfTrust);
@@ -151,14 +166,19 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
@@ -185,10 +205,11 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge1;
     Status result = sb->getRootOfTrustChallenge(&challenge1);
@@ -208,14 +229,20 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    // Execute the test only for KeyMint version >= 2.
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
@@ -240,14 +267,20 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    // Execute the test only for KeyMint version >= 2.
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 3cc11f6..7184613 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -358,8 +358,7 @@
 
 class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
   protected:
-    CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) {
-    }
+    CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
 
     void generateTestEekChain(size_t eekLength) {
         auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 54b6fdc..5bbae4c 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -142,6 +142,25 @@
         return Digest::NONE;
     }
 
+    optional<EcCurve> getCurveFromLength(int keySize) {
+        switch (keySize) {
+            case 224:
+                return EcCurve::P_224;
+                break;
+            case 256:
+                return EcCurve::P_256;
+                break;
+            case 384:
+                return EcCurve::P_384;
+                break;
+            case 521:
+                return EcCurve::P_521;
+                break;
+            default:
+                return {};
+        }
+    }
+
     bool GenerateKey(string transform, int keySize, bool sign = false) {
         if (transform == key_transform_) {
             return true;
@@ -184,6 +203,12 @@
         }
         if (algorithm == Algorithm::EC) {
             authSet.SetDefaultValidity();
+            std::optional<EcCurve> curve = getCurveFromLength(keySize);
+            if (!curve) {
+                std::cerr << "Error: invalid EC-Curve from size " << keySize << std::endl;
+                return false;
+            }
+            authSet.Authorization(TAG_EC_CURVE, curve.value());
         }
         error_ = GenerateKey(authSet);
         return error_ == ErrorCode::OK;
diff --git a/sensors/common/default/2.X/multihal/HalProxyCallback.cpp b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
index 3c1b17c..addefe8 100644
--- a/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
@@ -68,6 +68,10 @@
     std::vector<V2_1::Event> eventsOut;
     for (V2_1::Event event : events) {
         event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex);
+        if (event.sensorType == V2_1::SensorType::DYNAMIC_SENSOR_META) {
+            event.u.dynamic.sensorHandle =
+                    setSubHalIndex(event.u.dynamic.sensorHandle, mSubHalIndex);
+        }
         eventsOut.push_back(event);
         const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle);
         if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) {
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
index abff430..3fe6b52 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
@@ -7,4 +7,4 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    task_profiles ProcessCapacityHigh
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..bc62c7d 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,4 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    task_profiles ProcessCapacityHigh
diff --git a/usb/aidl/Android.bp b/usb/aidl/Android.bp
new file mode 100644
index 0000000..f71cacb
--- /dev/null
+++ b/usb/aidl/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.usb",
+    vendor_available: true,
+    srcs: ["android/hardware/usb/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl
new file mode 100644
index 0000000..24c6966
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum ContaminantDetectionStatus {
+  NOT_SUPPORTED = 0,
+  DISABLED = 1,
+  NOT_DETECTED = 2,
+  DETECTED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl
new file mode 100644
index 0000000..9979869
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum ContaminantProtectionMode {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl
new file mode 100644
index 0000000..9642261
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+enum ContaminantProtectionStatus {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+  DISABLED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
new file mode 100644
index 0000000..7513461
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+interface IUsb {
+  oneway void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
+  oneway void enableUsbData(in String portName, boolean enable, long transactionId);
+  oneway void queryPortStatus(long transactionId);
+  oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
+  oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
new file mode 100644
index 0000000..57be590
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+interface IUsbCallback {
+  oneway void notifyPortStatusChange(in android.hardware.usb.PortStatus[] currentPortStatus, in android.hardware.usb.Status retval);
+  oneway void notifyRoleSwitchStatus(in String portName, in android.hardware.usb.PortRole newRole, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyEnableUsbDataStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyContaminantEnabledStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyQueryPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl
new file mode 100644
index 0000000..105b316
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PortDataRole {
+  NONE = 0,
+  HOST = 1,
+  DEVICE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl
new file mode 100644
index 0000000..34e4334
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+enum PortMode {
+  NONE = 0,
+  UFP = 1,
+  DFP = 2,
+  DRP = 3,
+  AUDIO_ACCESSORY = 4,
+  DEBUG_ACCESSORY = 5,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl
new file mode 100644
index 0000000..0e6f3fb
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PortPowerRole {
+  NONE = 0,
+  SOURCE = 1,
+  SINK = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl
new file mode 100644
index 0000000..c66aecc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+union PortRole {
+  android.hardware.usb.PortPowerRole powerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortDataRole dataRole;
+  android.hardware.usb.PortMode mode;
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
new file mode 100644
index 0000000..78dcfac
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+parcelable PortStatus {
+  String portName;
+  android.hardware.usb.PortDataRole currentDataRole = android.hardware.usb.PortDataRole.NONE;
+  android.hardware.usb.PortPowerRole currentPowerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortMode currentMode = android.hardware.usb.PortMode.NONE;
+  boolean canChangeMode;
+  boolean canChangeDataRole;
+  boolean canChangePowerRole;
+  android.hardware.usb.PortMode[] supportedModes;
+  android.hardware.usb.ContaminantProtectionMode[] supportedContaminantProtectionModes;
+  boolean supportsEnableContaminantPresenceProtection;
+  android.hardware.usb.ContaminantProtectionStatus contaminantProtectionStatus = android.hardware.usb.ContaminantProtectionStatus.NONE;
+  boolean supportsEnableContaminantPresenceDetection;
+  android.hardware.usb.ContaminantDetectionStatus contaminantDetectionStatus = android.hardware.usb.ContaminantDetectionStatus.NOT_SUPPORTED;
+  boolean usbDataEnabled;
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl
new file mode 100644
index 0000000..f28fc2a
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  INVALID_ARGUMENT = 2,
+  UNRECOGNIZED_ROLE = 3,
+  NOT_SUPPORTED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl
new file mode 100644
index 0000000..d9bc576
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl
@@ -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.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+enum ContaminantDetectionStatus {
+    /**
+     * Contaminant presence detection is not supported.
+     */
+    NOT_SUPPORTED = 0,
+    /**
+     * Contaminant presence detection is supported but disabled.
+     */
+    DISABLED = 1,
+    /**
+     * Contaminant presence detection is enabled and contaminant not detected.
+     */
+    NOT_DETECTED = 2,
+    /**
+     * Contaminant presence detection is enabled and contaminant detected.
+     */
+    DETECTED = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
new file mode 100644
index 0000000..47c073d
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
@@ -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 android.hardware.usb;
+
+@VintfStability
+enum ContaminantProtectionMode {
+    /**
+     * No action performed upon detection of contaminant presence.
+     */
+    NONE = 0,
+    /**
+     * Upon detection of contaminant presence, Port is forced to sink only
+     * mode where a port shall only detect chargers until contaminant presence
+     * is no longer detected.
+     */
+    FORCE_SINK = 1,
+    /**
+     * Upon detection of contaminant presence, Port is forced to source only
+     * mode where a port shall only detect usb accessories such as headsets
+     * until contaminant presence is no longer detected.
+     */
+    FORCE_SOURCE = 2,
+    /**
+     * Upon detection of contaminant presence, port is disabled until contaminant
+     * presence is no longer detected. In the disabled state port will
+     * not respond to connection of chargers or usb accessories.
+     */
+    FORCE_DISABLE = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl
new file mode 100644
index 0000000..c4fa979
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl
@@ -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.
+ */
+
+package android.hardware.usb;
+
+import android.hardware.usb.ContaminantProtectionMode;
+
+@VintfStability
+enum ContaminantProtectionStatus {
+    /**
+     * No action performed upon detection of contaminant presence.
+     */
+    NONE = 0,
+    /**
+     * Upon detection of contaminant presence, Port is forced to sink only
+     * mode where a port shall only detect chargers until contaminant presence
+     * is no longer detected.
+     */
+    FORCE_SINK = 1,
+    /**
+     * Upon detection of contaminant presence, Port is forced to source only
+     * mode where a port shall only detect usb accessories such as headsets
+     * until contaminant presence is no longer detected.
+     */
+    FORCE_SOURCE = 2,
+    /**
+     * Upon detection of contaminant presence, port is disabled until contaminant
+     * presence is no longer detected. In the disabled state port will
+     * not respond to connection of chargers or usb accessories.
+     */
+    FORCE_DISABLE = 3,
+    /**
+     * Client disabled cotaminant protection by calling
+     * enableContaminantPresencePortProtection set to false. Low level drivers should
+     * not autmomously take any corrective action when contaminant presence is detected.
+     */
+    DISABLED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/IUsb.aidl b/usb/aidl/android/hardware/usb/IUsb.aidl
new file mode 100644
index 0000000..9a8f000
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/IUsb.aidl
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+import android.hardware.usb.IUsbCallback;
+import android.hardware.usb.PortRole;
+
+@VintfStability
+oneway interface IUsb {
+    /**
+     * When supportsEnableContaminantPresenceDetection is true,
+     * enableContaminantPresenceDetection enables/disables contaminant
+     * presence detection algorithm. Calling enableContaminantPresenceDetection
+     * when supportsEnableContaminantPresenceDetection is false does
+     * not have any effect.
+     * Change in contantaminant presence status should be notified to the
+     * client via notifyPortStatusChange through PortStatus.
+     *
+     * @param portName name of the port.
+     * @param enable true Enable contaminant presence detection algorithm.
+     *               false Disable contaminant presence detection algorithm.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
+
+    /**
+     * This function is used to enable/disable USB data controller.
+     *
+     * @param portName Name of the port.
+     * @param enable   true Enable USB data signaling.
+     *                 false Disable USB data signaling.
+     * @param transactionId ID to be used when invoking the callback.
+     *
+     */
+    void enableUsbData(in String portName, boolean enable, long transactionId);
+
+    /**
+     * This functions is used to request the hal for the current status
+     * status of the Type-C ports. The result of the query would be sent
+     * through the IUsbCallback object's notifyRoleSwitchStatus
+     * to the caller. This api would would let the caller know of the number
+     * of type-c ports that are present and their connection status through the
+     * PortStatus type.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void queryPortStatus(long transactionId);
+
+    /**
+     * This function is used to register a callback function which is
+     * called by the HAL to inform the client of port status updates and
+     * result of the requested operation. Please refer IUsbCallback for
+     * complete description of when each of the IUsbCallback's interface
+     * methods is expected to be called.
+     *
+     * @param callback IUsbCallback object used to convey status to the
+     * userspace.
+     */
+    void setCallback(in IUsbCallback callback);
+
+    /**
+     * This function is used to change the port role of a specific port.
+     * For example, when DR_SWAP or PR_SWAP is supported.
+     * The status of the role switch will be informed through IUsbCallback
+     * object's notifyPortStatusChange method.
+     *
+     * @param portName name of the port for which the role has to be changed
+     * @param role the new port role.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void switchRole(in String portName, in PortRole role, long transactionId);
+}
diff --git a/usb/aidl/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
new file mode 100644
index 0000000..232a15b
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.usb;
+
+import android.hardware.usb.PortRole;
+import android.hardware.usb.PortStatus;
+import android.hardware.usb.Status;
+
+/**
+ * Callback object used for all the IUsb async methods which expects a result.
+ * Caller is expected to register the callback object using setCallback method
+ * to receive updates on the PortStatus.
+ */
+@VintfStability
+oneway interface IUsbCallback {
+    /**
+     * Used to convey the current port status to the caller.
+     * Must be called either when PortState changes due to the port partner or
+     * when caller requested for the PortStatus update through queryPortStatus.
+     *
+     * @param currentPortStatus describes the status of all the USB ports in the
+     *                          device.
+     * @param retval SUCCESS when the required information was enquired form
+     *               kernel and the PortStatus object was built.
+     *               ERROR otherwise.
+     */
+    void notifyPortStatusChange(in PortStatus[] currentPortStatus, in Status retval);
+
+    /**
+     * Used to notify the result of the switchRole call to the caller.
+     *
+     * @param portName name of the port for which the roleswap is requested.
+     * @param newRole the new role requested by the caller.
+     * @param retval SUCCESS if the role switch succeeded. FAILURE otherwise.
+     * @param transactionId  transactionId sent during switchRole request.
+     */
+    void notifyRoleSwitchStatus(in String portName, in PortRole newRole, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the result of notifyEnableUsbDataStatus call to the caller.
+     *
+     * @param portName name of the port for which the enableUsbData is requested.
+     * @param enable true when usb data is enabled.
+     *               false when usb data is disabled.
+     * @param retval SUCCESS if current request succeeded. FAILURE otherwise.
+     * @param transactionId transactionId sent during enableUsbData request.
+     */
+    void notifyEnableUsbDataStatus(in String portName, boolean enable, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the result of enableContaminantPresenceDetection.
+     *
+     * @param portName name of the port for which contaminant detection is enabled/disabled.
+     * @param enable true when contaminant detection is enabled.
+     *               false when disabled.
+     * @param retval SUCCESS if the request for enabling/disabling contamiant detection succeeds.
+     *               FAILURE otherwise.
+     * @param transactionId transactionId sent during queryPortStatus request
+     */
+    void notifyContaminantEnabledStatus(in String portName, boolean enable, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the request to query port status.
+     *
+     * @param portName name of the port for which port status is queried.
+     * @param retval SUCCESS if the port query succeeded. FAILURE otherwise.
+     * @param transactionId transactionId sent during queryPortStatus request
+     */
+    void notifyQueryPortStatus(in String portName, in Status retval, long transactionId);
+}
diff --git a/usb/aidl/android/hardware/usb/PortDataRole.aidl b/usb/aidl/android/hardware/usb/PortDataRole.aidl
new file mode 100644
index 0000000..a69f977
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortDataRole.aidl
@@ -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.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+enum PortDataRole {
+    /**
+     * Indicates that the port does not have a data role.
+     * In case of DRP, the current data role of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that the port is acting as a host for data.
+     */
+    HOST = 1,
+    /**
+     * Indicated that the port is acting as a device for data.
+     */
+    DEVICE = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PortMode.aidl b/usb/aidl/android/hardware/usb/PortMode.aidl
new file mode 100644
index 0000000..399f0eb
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.PortMode;
+
+@VintfStability
+enum PortMode {
+    /**
+     * Indicates that the port does not have a mode.
+     * In case of DRP, the current mode of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that port can only act as device for data and sink for power.
+     */
+    UFP = 1,
+    /**
+     * Indicates the port can only act as host for data and source for power.
+     */
+    DFP = 2,
+    /**
+     * Indicates can either act as UFP or DFP at a given point of time.
+     */
+    DRP = 3,
+    /*
+     * Indicates that the port supports Audio Accessory mode.
+     */
+    AUDIO_ACCESSORY = 4,
+    /*
+     * Indicates that the port supports Debug Accessory mode.
+     */
+    DEBUG_ACCESSORY = 5,
+}
diff --git a/usb/aidl/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/android/hardware/usb/PortPowerRole.aidl
new file mode 100644
index 0000000..ae3dc47
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortPowerRole.aidl
@@ -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.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+enum PortPowerRole {
+    /**
+     * Indicates that the port does not have a power role.
+     * In case of DRP, the current power role of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that the port is supplying power to the other port.
+     */
+    SOURCE = 1,
+    /**
+     * Indicates that the port is sinking power from the other port.
+     */
+    SINK = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PortRole.aidl b/usb/aidl/android/hardware/usb/PortRole.aidl
new file mode 100644
index 0000000..e0429c8
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortRole.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.usb;
+
+import android.hardware.usb.PortDataRole;
+import android.hardware.usb.PortMode;
+import android.hardware.usb.PortPowerRole;
+
+/**
+ * Used as a container to send port role information.
+ */
+@VintfStability
+union PortRole {
+    PortPowerRole powerRole = PortPowerRole.NONE;
+    PortDataRole dataRole;
+    PortMode mode;
+}
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
new file mode 100644
index 0000000..8afe009
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -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.
+ */
+
+package android.hardware.usb;
+
+import android.hardware.usb.ContaminantDetectionStatus;
+import android.hardware.usb.ContaminantProtectionMode;
+import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.PortDataRole;
+import android.hardware.usb.PortMode;
+import android.hardware.usb.PortPowerRole;
+
+@VintfStability
+parcelable PortStatus {
+    /**
+     * Name of the port.
+     * Used as the port's id by the caller.
+     */
+    String portName;
+    /**
+     * Data role of the port.
+     */
+    PortDataRole currentDataRole = PortDataRole.NONE;
+    /**
+     * Power Role of thte port.
+     */
+    PortPowerRole currentPowerRole = PortPowerRole.NONE;
+    /**
+     * Mode in which the port is connected.
+     * Can be UFP or DFP or AUDIO_ACCESSORY or
+     * DEBUG_ACCESSORY.
+     */
+    PortMode currentMode = PortMode.NONE;
+    /**
+     * True indicates that the port's mode can
+     * be changed. False otherwise.
+     */
+    boolean canChangeMode;
+    /**
+     * True indicates that the port's data role
+     * can be changed. False otherwise.
+     * For example, true if Type-C PD PD_SWAP
+     * is supported.
+     */
+    boolean canChangeDataRole;
+    /**
+     * True indicates that the port's power role
+     * can be changed. False otherwise.
+     * For example, true if Type-C PD PR_SWAP
+     * is supported.
+     */
+    boolean canChangePowerRole;
+    /**
+     * Identifies the type of the local port.
+     *
+     * UFP - Indicates that port can only act as device for
+     *       data and sink for power.
+     * DFP - Indicates the port can only act as host for data
+     *       and source for power.
+     * DRP - Indicates can either act as UFP or DFP at a
+     *       given point of time.
+     * AUDIO_ACCESSORY -  Indicates that the port supports
+     *                    Audio Accessory mode.
+     * DEBUG_ACCESSORY - Indicates that the port supports
+     *                   Debug Accessory mode.
+     */
+    PortMode[] supportedModes;
+    /**
+     * Contaminant presence protection modes supported by the port.
+     */
+    ContaminantProtectionMode[] supportedContaminantProtectionModes;
+    /**
+     * Client can enable/disable contaminant presence protection through
+     * enableContaminantPresenceProtection when true.
+     */
+    boolean supportsEnableContaminantPresenceProtection;
+    /**
+     * Contaminant presence protection modes currently active for the port.
+     */
+    ContaminantProtectionStatus contaminantProtectionStatus = ContaminantProtectionStatus.NONE;
+    /**
+     * Client can enable/disable contaminant presence detection through
+     * enableContaminantPresenceDetection when true.
+     */
+    boolean supportsEnableContaminantPresenceDetection;
+    /**
+     * Current status of contaminant detection algorithm.
+     */
+    ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
+    /**
+     * UsbData status of the port.
+     */
+    boolean usbDataEnabled;
+}
diff --git a/usb/aidl/android/hardware/usb/Status.aidl b/usb/aidl/android/hardware/usb/Status.aidl
new file mode 100644
index 0000000..468ba4a
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/Status.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    SUCCESS = 0,
+    /**
+     * error value when the HAL operation fails for reasons not listed here.
+     */
+    ERROR = 1,
+    /**
+     * error value returned when input argument is invalid.
+     */
+    INVALID_ARGUMENT = 2,
+    /**
+     * error value returned when role string is unrecognized.
+     */
+    UNRECOGNIZED_ROLE = 3,
+    /**
+     * Error value returned when the operation is not supported.
+     */
+    NOT_SUPPORTED = 4,
+}
diff --git a/usb/aidl/conversion.log b/usb/aidl/conversion.log
new file mode 100644
index 0000000..c090446
--- /dev/null
+++ b/usb/aidl/conversion.log
@@ -0,0 +1,11 @@
+Notes relating to hidl2aidl conversion of android.hardware.usb@1.3 to android.hardware.usb (if any) follow:
+Unhandled comments from android.hardware.usb@1.1::types follow. Consider using hidl-lint to locate these and fixup as many as possible.
+ // NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
+ // changed to 'PortMode' which the convention dictates.
+ // NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
+ // changed to 'PortStatus' which the convention dictates.
+
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+END OF LOG
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
new file mode 100644
index 0000000..7cb2822
--- /dev/null
+++ b/usb/aidl/default/Android.bp
@@ -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 {
+    // 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.usb-service.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.usb-service.example.rc"],
+    vintf_fragments: ["android.hardware.usb-service.example.xml"],
+    vendor: true,
+    srcs: [
+        "service.cpp",
+        "Usb.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.usb-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+	"libcutils",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
new file mode 100644
index 0000000..1105376
--- /dev/null
+++ b/usb/aidl/default/Usb.cpp
@@ -0,0 +1,693 @@
+/*
+ * 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 "android.hardware.usb.aidl-service"
+
+#include <aidl/android/hardware/usb/PortRole.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <assert.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <chrono>
+#include <regex>
+#include <thread>
+#include <unordered_map>
+
+#include <cutils/uevent.h>
+#include <sys/epoll.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "Usb.h"
+
+using android::base::GetProperty;
+using android::base::Trim;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+
+constexpr char kTypecPath[] = "/sys/class/typec/";
+constexpr char kDataRoleNode[] = "/data_role";
+constexpr char kPowerRoleNode[] = "/power_role";
+
+// Set by the signal handler to destroy the thread
+volatile bool destroyThread;
+
+void queryVersionHelper(android::hardware::usb::Usb *usb,
+                        std::vector<PortStatus> *currentPortStatus);
+
+ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyEnableUsbDataStatus(
+            in_portName, true, in_enable ? Status::SUCCESS : Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("notifyEnableUsbDataStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+    queryVersionHelper(this, &currentPortStatus);
+
+    return ScopedAStatus::ok();
+}
+
+Status queryMoistureDetectionStatus(std::vector<PortStatus> *currentPortStatus) {
+    string enabled, status, path, DetectedPath;
+
+    for (int i = 0; i < currentPortStatus->size(); i++) {
+        (*currentPortStatus)[i].supportedContaminantProtectionModes
+                .push_back(ContaminantProtectionMode::NONE);
+        (*currentPortStatus)[i].contaminantProtectionStatus
+                = ContaminantProtectionStatus::NONE;
+        (*currentPortStatus)[i].contaminantDetectionStatus
+                = ContaminantDetectionStatus::NOT_SUPPORTED;
+        (*currentPortStatus)[i].supportsEnableContaminantPresenceDetection = false;
+        (*currentPortStatus)[i].supportsEnableContaminantPresenceProtection = false;
+    }
+
+    return Status::SUCCESS;
+}
+
+string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
+    string node(kTypecPath + portName);
+
+    switch (tag) {
+        case PortRole::dataRole:
+            return node + kDataRoleNode;
+        case PortRole::powerRole:
+            return node + kPowerRoleNode;
+        case PortRole::mode:
+            return node + "/port_type";
+        default:
+            return "";
+    }
+}
+
+string convertRoletoString(PortRole role) {
+    if (role.getTag() == PortRole::powerRole) {
+        if (role.get<PortRole::powerRole>() == PortPowerRole::SOURCE)
+            return "source";
+        else if (role.get<PortRole::powerRole>() == PortPowerRole::SINK)
+            return "sink";
+    } else if (role.getTag() == PortRole::dataRole) {
+        if (role.get<PortRole::dataRole>() == PortDataRole::HOST)
+            return "host";
+        if (role.get<PortRole::dataRole>() == PortDataRole::DEVICE)
+            return "device";
+    } else if (role.getTag() == PortRole::mode) {
+        if (role.get<PortRole::mode>() == PortMode::UFP)
+            return "sink";
+        if (role.get<PortRole::mode>() == PortMode::DFP)
+            return "source";
+    }
+    return "none";
+}
+
+void extractRole(string *roleName) {
+    std::size_t first, last;
+
+    first = roleName->find("[");
+    last = roleName->find("]");
+
+    if (first != string::npos && last != string::npos) {
+        *roleName = roleName->substr(first + 1, last - first - 1);
+    }
+}
+
+void switchToDrp(const string &portName) {
+    string filename = appendRoleNodeHelper(string(portName.c_str()), PortRole::mode);
+    FILE *fp;
+
+    if (filename != "") {
+        fp = fopen(filename.c_str(), "w");
+        if (fp != NULL) {
+            int ret = fputs("dual", fp);
+            fclose(fp);
+            if (ret == EOF)
+                ALOGE("Fatal: Error while switching back to drp");
+        } else {
+            ALOGE("Fatal: Cannot open file to switch back to drp");
+        }
+    } else {
+        ALOGE("Fatal: invalid node type");
+    }
+}
+
+bool switchMode(const string &portName, const PortRole &in_role, struct Usb *usb) {
+    string filename = appendRoleNodeHelper(string(portName.c_str()), in_role.getTag());
+    string written;
+    FILE *fp;
+    bool roleSwitch = false;
+
+    if (filename == "") {
+        ALOGE("Fatal: invalid node type");
+        return false;
+    }
+
+    fp = fopen(filename.c_str(), "w");
+    if (fp != NULL) {
+        // Hold the lock here to prevent loosing connected signals
+        // as once the file is written the partner added signal
+        // can arrive anytime.
+        pthread_mutex_lock(&usb->mPartnerLock);
+        usb->mPartnerUp = false;
+        int ret = fputs(convertRoletoString(in_role).c_str(), fp);
+        fclose(fp);
+
+        if (ret != EOF) {
+            struct timespec to;
+            struct timespec now;
+
+        wait_again:
+            clock_gettime(CLOCK_MONOTONIC, &now);
+            to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT;
+            to.tv_nsec = now.tv_nsec;
+
+            int err = pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to);
+            // There are no uevent signals which implies role swap timed out.
+            if (err == ETIMEDOUT) {
+                ALOGI("uevents wait timedout");
+                // Validity check.
+            } else if (!usb->mPartnerUp) {
+                goto wait_again;
+                // Role switch succeeded since usb->mPartnerUp is true.
+            } else {
+                roleSwitch = true;
+            }
+        } else {
+            ALOGI("Role switch failed while wrting to file");
+        }
+        pthread_mutex_unlock(&usb->mPartnerLock);
+    }
+
+    if (!roleSwitch)
+        switchToDrp(string(portName.c_str()));
+
+    return roleSwitch;
+}
+
+Usb::Usb()
+    : mLock(PTHREAD_MUTEX_INITIALIZER),
+      mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
+      mPartnerLock(PTHREAD_MUTEX_INITIALIZER),
+      mPartnerUp(false)
+{
+    pthread_condattr_t attr;
+    if (pthread_condattr_init(&attr)) {
+        ALOGE("pthread_condattr_init failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
+        ALOGE("pthread_condattr_setclock failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_cond_init(&mPartnerCV, &attr)) {
+        ALOGE("pthread_cond_init failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_condattr_destroy(&attr)) {
+        ALOGE("pthread_condattr_destroy failed: %s", strerror(errno));
+        abort();
+    }
+}
+
+ScopedAStatus Usb::switchRole(const string& in_portName,
+        const PortRole& in_role, int64_t in_transactionId) {
+    string filename = appendRoleNodeHelper(string(in_portName.c_str()), in_role.getTag());
+    string written;
+    FILE *fp;
+    bool roleSwitch = false;
+
+    if (filename == "") {
+        ALOGE("Fatal: invalid node type");
+        return ScopedAStatus::ok();
+    }
+
+    pthread_mutex_lock(&mRoleSwitchLock);
+
+    ALOGI("filename write: %s role:%s", filename.c_str(), convertRoletoString(in_role).c_str());
+
+    if (in_role.getTag() == PortRole::mode) {
+        roleSwitch = switchMode(in_portName, in_role, this);
+    } else {
+        fp = fopen(filename.c_str(), "w");
+        if (fp != NULL) {
+            int ret = fputs(convertRoletoString(in_role).c_str(), fp);
+            fclose(fp);
+            if ((ret != EOF) && ReadFileToString(filename, &written)) {
+                written = Trim(written);
+                extractRole(&written);
+                ALOGI("written: %s", written.c_str());
+                if (written == convertRoletoString(in_role)) {
+                    roleSwitch = true;
+                } else {
+                    ALOGE("Role switch failed");
+                }
+            } else {
+                ALOGE("failed to update the new role");
+            }
+        } else {
+            ALOGE("fopen failed");
+        }
+    }
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+         ScopedAStatus ret = mCallback->notifyRoleSwitchStatus(
+            in_portName, in_role, roleSwitch ? Status::SUCCESS : Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("RoleSwitchStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+    pthread_mutex_unlock(&mRoleSwitchLock);
+
+    return ScopedAStatus::ok();
+}
+
+Status getAccessoryConnected(const string &portName, string *accessory) {
+    string filename = kTypecPath + portName + "-partner/accessory_mode";
+
+    if (!ReadFileToString(filename, accessory)) {
+        ALOGE("getAccessoryConnected: Failed to open filesystem node: %s", filename.c_str());
+        return Status::ERROR;
+    }
+    *accessory = Trim(*accessory);
+
+    return Status::SUCCESS;
+}
+
+Status getCurrentRoleHelper(const string &portName, bool connected, PortRole *currentRole) {
+    string filename;
+    string roleName;
+    string accessory;
+
+    // Mode
+
+    if (currentRole->getTag() == PortRole::powerRole) {
+        filename = kTypecPath + portName + kPowerRoleNode;
+        currentRole->set<PortRole::powerRole>(PortPowerRole::NONE);
+    } else if (currentRole->getTag() == PortRole::dataRole) {
+        filename = kTypecPath + portName + kDataRoleNode;
+        currentRole->set<PortRole::dataRole>(PortDataRole::NONE);
+    } else if (currentRole->getTag() == PortRole::mode) {
+        filename = kTypecPath + portName + kDataRoleNode;
+        currentRole->set<PortRole::mode>(PortMode::NONE);
+    } else {
+        return Status::ERROR;
+    }
+
+    if (!connected)
+        return Status::SUCCESS;
+
+    if (currentRole->getTag() == PortRole::mode) {
+        if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
+            return Status::ERROR;
+        }
+        if (accessory == "analog_audio") {
+            currentRole->set<PortRole::mode>(PortMode::AUDIO_ACCESSORY);
+            return Status::SUCCESS;
+        } else if (accessory == "debug") {
+            currentRole->set<PortRole::mode>(PortMode::DEBUG_ACCESSORY);
+            return Status::SUCCESS;
+        }
+    }
+
+    if (!ReadFileToString(filename, &roleName)) {
+        ALOGE("getCurrentRole: Failed to open filesystem node: %s", filename.c_str());
+        return Status::ERROR;
+    }
+
+    roleName = Trim(roleName);
+    extractRole(&roleName);
+
+    if (roleName == "source") {
+        currentRole->set<PortRole::powerRole>(PortPowerRole::SOURCE);
+    } else if (roleName == "sink") {
+        currentRole->set<PortRole::powerRole>(PortPowerRole::SINK);
+    } else if (roleName == "host") {
+        if (currentRole->getTag() == PortRole::dataRole)
+            currentRole->set<PortRole::dataRole>(PortDataRole::HOST);
+        else
+            currentRole->set<PortRole::mode>(PortMode::DFP);
+    } else if (roleName == "device") {
+        if (currentRole->getTag() == PortRole::dataRole)
+            currentRole->set<PortRole::dataRole>(PortDataRole::DEVICE);
+        else
+            currentRole->set<PortRole::mode>(PortMode::UFP);
+    } else if (roleName != "none") {
+        /* case for none has already been addressed.
+         * so we check if the role isn't none.
+         */
+        return Status::UNRECOGNIZED_ROLE;
+    }
+
+    return Status::SUCCESS;
+}
+
+Status getTypeCPortNamesHelper(std::unordered_map<string, bool> *names) {
+    DIR *dp;
+
+    dp = opendir(kTypecPath);
+    if (dp != NULL) {
+        struct dirent *ep;
+
+        while ((ep = readdir(dp))) {
+            if (ep->d_type == DT_LNK) {
+                if (string::npos == string(ep->d_name).find("-partner")) {
+                    std::unordered_map<string, bool>::const_iterator portName =
+                        names->find(ep->d_name);
+                    if (portName == names->end()) {
+                        names->insert({ep->d_name, false});
+                    }
+                } else {
+                    (*names)[std::strtok(ep->d_name, "-")] = true;
+                }
+            }
+        }
+        closedir(dp);
+        return Status::SUCCESS;
+    }
+
+    ALOGE("Failed to open /sys/class/typec");
+    return Status::ERROR;
+}
+
+bool canSwitchRoleHelper(const string &portName) {
+    string filename = kTypecPath + portName + "-partner/supports_usb_power_delivery";
+    string supportsPD;
+
+    if (ReadFileToString(filename, &supportsPD)) {
+        supportsPD = Trim(supportsPD);
+        if (supportsPD == "yes") {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+Status getPortStatusHelper(std::vector<PortStatus> *currentPortStatus) {
+    std::unordered_map<string, bool> names;
+    Status result = getTypeCPortNamesHelper(&names);
+    int i = -1;
+
+    if (result == Status::SUCCESS) {
+        currentPortStatus->resize(names.size());
+        for (std::pair<string, bool> port : names) {
+            i++;
+            ALOGI("%s", port.first.c_str());
+            (*currentPortStatus)[i].portName = port.first;
+
+            PortRole currentRole;
+            currentRole.set<PortRole::powerRole>(PortPowerRole::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS){
+                (*currentPortStatus)[i].currentPowerRole = currentRole.get<PortRole::powerRole>();
+            } else {
+                ALOGE("Error while retrieving portNames");
+                goto done;
+            }
+
+            currentRole.set<PortRole::dataRole>(PortDataRole::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS) {
+                (*currentPortStatus)[i].currentDataRole = currentRole.get<PortRole::dataRole>();
+            } else {
+                ALOGE("Error while retrieving current port role");
+                goto done;
+            }
+
+            currentRole.set<PortRole::mode>(PortMode::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS) {
+                (*currentPortStatus)[i].currentMode = currentRole.get<PortRole::mode>();
+            } else {
+                ALOGE("Error while retrieving current data role");
+                goto done;
+            }
+
+            (*currentPortStatus)[i].canChangeMode = true;
+            (*currentPortStatus)[i].canChangeDataRole =
+                port.second ? canSwitchRoleHelper(port.first) : false;
+            (*currentPortStatus)[i].canChangePowerRole =
+                port.second ? canSwitchRoleHelper(port.first) : false;
+
+            (*currentPortStatus)[i].supportedModes.push_back(PortMode::DRP);
+            (*currentPortStatus)[i].usbDataEnabled = true;
+
+            ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
+                "usbDataEnabled:%d",
+                i, port.first.c_str(), port.second,
+                (*currentPortStatus)[i].canChangeMode,
+                (*currentPortStatus)[i].canChangeDataRole,
+                (*currentPortStatus)[i].canChangePowerRole, 0);
+        }
+
+        return Status::SUCCESS;
+    }
+done:
+    return Status::ERROR;
+}
+
+void queryVersionHelper(android::hardware::usb::Usb *usb,
+                        std::vector<PortStatus> *currentPortStatus) {
+    Status status;
+    pthread_mutex_lock(&usb->mLock);
+    status = getPortStatusHelper(currentPortStatus);
+    queryMoistureDetectionStatus(currentPortStatus);
+    if (usb->mCallback != NULL) {
+        ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
+            status);
+        if (!ret.isOk())
+            ALOGE("queryPortStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGI("Notifying userspace skipped. Callback is NULL");
+    }
+    pthread_mutex_unlock(&usb->mLock);
+}
+
+ScopedAStatus Usb::queryPortStatus(int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    queryVersionHelper(this, &currentPortStatus);
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyQueryPortStatus(
+            "all", Status::SUCCESS, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("notifyQueryPortStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Usb::enableContaminantPresenceDetection(const string& in_portName,
+        bool /*in_enable*/, int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyContaminantEnabledStatus(
+            in_portName, false, Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("enableContaminantPresenceDetection  error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+
+    queryVersionHelper(this, &currentPortStatus);
+    return ScopedAStatus::ok();
+}
+
+
+struct data {
+    int uevent_fd;
+    ::aidl::android::hardware::usb::Usb *usb;
+};
+
+static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
+    char msg[UEVENT_MSG_LEN + 2];
+    char *cp;
+    int n;
+
+    n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
+    if (n <= 0)
+        return;
+    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
+        return;
+
+    msg[n] = '\0';
+    msg[n + 1] = '\0';
+    cp = msg;
+
+    while (*cp) {
+        if (std::regex_match(cp, std::regex("(add)(.*)(-partner)"))) {
+            ALOGI("partner added");
+            pthread_mutex_lock(&payload->usb->mPartnerLock);
+            payload->usb->mPartnerUp = true;
+            pthread_cond_signal(&payload->usb->mPartnerCV);
+            pthread_mutex_unlock(&payload->usb->mPartnerLock);
+        } else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_"))) {
+            std::vector<PortStatus> currentPortStatus;
+            queryVersionHelper(payload->usb, &currentPortStatus);
+
+            // Role switch is not in progress and port is in disconnected state
+            if (!pthread_mutex_trylock(&payload->usb->mRoleSwitchLock)) {
+                for (unsigned long i = 0; i < currentPortStatus.size(); i++) {
+                    DIR *dp =
+                        opendir(string(kTypecPath +
+                                       string(currentPortStatus[i].portName.c_str()) +
+                                       "-partner").c_str());
+                    if (dp == NULL) {
+                        switchToDrp(currentPortStatus[i].portName);
+                    } else {
+                        closedir(dp);
+                    }
+                }
+                pthread_mutex_unlock(&payload->usb->mRoleSwitchLock);
+            }
+            break;
+        } /* advance to after the next \0 */
+        while (*cp++) {
+        }
+    }
+}
+
+void *work(void *param) {
+    int epoll_fd, uevent_fd;
+    struct epoll_event ev;
+    int nevents = 0;
+    struct data payload;
+
+    uevent_fd = uevent_open_socket(UEVENT_MAX_EVENTS * UEVENT_MSG_LEN, true);
+
+    if (uevent_fd < 0) {
+        ALOGE("uevent_init: uevent_open_socket failed\n");
+        return NULL;
+    }
+
+    payload.uevent_fd = uevent_fd;
+    payload.usb = (::aidl::android::hardware::usb::Usb *)param;
+
+    fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
+
+    ev.events = EPOLLIN;
+    ev.data.ptr = (void *)uevent_event;
+
+    epoll_fd = epoll_create(UEVENT_MAX_EVENTS);
+    if (epoll_fd == -1) {
+        ALOGE("epoll_create failed; errno=%d", errno);
+        goto error;
+    }
+
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
+        ALOGE("epoll_ctl failed; errno=%d", errno);
+        goto error;
+    }
+
+    while (!destroyThread) {
+        struct epoll_event events[UEVENT_MAX_EVENTS];
+
+        nevents = epoll_wait(epoll_fd, events, UEVENT_MAX_EVENTS, -1);
+        if (nevents == -1) {
+            if (errno == EINTR)
+                continue;
+            ALOGE("usb epoll_wait failed; errno=%d", errno);
+            break;
+        }
+
+        for (int n = 0; n < nevents; ++n) {
+            if (events[n].data.ptr)
+                (*(void (*)(int, struct data *payload))events[n].data.ptr)(events[n].events,
+                                                                           &payload);
+        }
+    }
+
+    ALOGI("exiting worker thread");
+error:
+    close(uevent_fd);
+
+    if (epoll_fd >= 0)
+        close(epoll_fd);
+
+    return NULL;
+}
+
+void sighandler(int sig) {
+    if (sig == SIGUSR1) {
+        destroyThread = true;
+        ALOGI("destroy set");
+        return;
+    }
+    signal(SIGUSR1, sighandler);
+}
+
+ScopedAStatus Usb::setCallback(
+        const shared_ptr<IUsbCallback>& in_callback) {
+
+    pthread_mutex_lock(&mLock);
+    if ((mCallback == NULL && in_callback == NULL) ||
+            (mCallback != NULL && in_callback != NULL)) {
+        mCallback = in_callback;
+        pthread_mutex_unlock(&mLock);
+        return ScopedAStatus::ok();
+    }
+
+    mCallback = in_callback;
+    ALOGI("registering callback");
+
+    if (mCallback == NULL) {
+        if  (!pthread_kill(mPoll, SIGUSR1)) {
+            pthread_join(mPoll, NULL);
+            ALOGI("pthread destroyed");
+        }
+        pthread_mutex_unlock(&mLock);
+        return ScopedAStatus::ok();
+    }
+
+    destroyThread = false;
+    signal(SIGUSR1, sighandler);
+
+    /*
+     * Create a background thread if the old callback value is NULL
+     * and being updated with a new value.
+     */
+    if (pthread_create(&mPoll, NULL, work, this)) {
+        ALOGE("pthread creation failed %d", errno);
+        mCallback = NULL;
+    }
+
+    pthread_mutex_unlock(&mLock);
+    return ScopedAStatus::ok();
+}
+
+} // namespace usb
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/usb/aidl/default/Usb.h b/usb/aidl/default/Usb.h
new file mode 100644
index 0000000..bca86ae
--- /dev/null
+++ b/usb/aidl/default/Usb.h
@@ -0,0 +1,76 @@
+/*
+ * 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/file.h>
+#include <aidl/android/hardware/usb/BnUsb.h>
+#include <aidl/android/hardware/usb/BnUsbCallback.h>
+#include <utils/Log.h>
+
+#define UEVENT_MSG_LEN     2048
+#define UEVENT_MAX_EVENTS  64
+// The type-c stack waits for 4.5 - 5.5 secs before declaring a port non-pd.
+// The -partner directory would not be created until this is done.
+// Having a margin of ~3 secs for the directory and other related bookeeping
+// structures created and uvent fired.
+#define PORT_TYPE_TIMEOUT 8
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+
+using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::PortRole;
+using ::android::base::ReadFileToString;
+using ::android::base::WriteStringToFile;
+using ::android::sp;
+using ::ndk::ScopedAStatus;
+using ::std::shared_ptr;
+using ::std::string;
+
+struct Usb : public BnUsb {
+    Usb();
+
+    ScopedAStatus enableContaminantPresenceDetection(const std::string& in_portName,
+            bool in_enable, int64_t in_transactionId) override;
+    ScopedAStatus queryPortStatus(int64_t in_transactionId) override;
+    ScopedAStatus setCallback(const shared_ptr<IUsbCallback>& in_callback) override;
+    ScopedAStatus switchRole(const string& in_portName, const PortRole& in_role,
+            int64_t in_transactionId) override;
+    ScopedAStatus enableUsbData(const string& in_portName, bool in_enable,
+            int64_t in_transactionId) override;
+
+    shared_ptr<IUsbCallback> mCallback;
+    // Protects mCallback variable
+    pthread_mutex_t mLock;
+    // Protects roleSwitch operation
+    pthread_mutex_t mRoleSwitchLock;
+    // Threads waiting for the partner to come back wait here
+    pthread_cond_t mPartnerCV;
+    // lock protecting mPartnerCV
+    pthread_mutex_t mPartnerLock;
+    // Variable to signal partner coming back online after type switch
+    bool mPartnerUp;
+  private:
+    pthread_t mPoll;
+};
+
+} // namespace usb
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/usb/aidl/default/android.hardware.usb-service.example.rc b/usb/aidl/default/android.hardware.usb-service.example.rc
new file mode 100644
index 0000000..335bca7
--- /dev/null
+++ b/usb/aidl/default/android.hardware.usb-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.usb_default /vendor/bin/hw/android.hardware.usb-service.example
+    class hal
+    user system
+    group system
diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml
new file mode 100644
index 0000000..6088194
--- /dev/null
+++ b/usb/aidl/default/android.hardware.usb-service.example.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.usb</name>
+        <version>1</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/usb/aidl/default/service.cpp b/usb/aidl/default/service.cpp
new file mode 100644
index 0000000..398458a
--- /dev/null
+++ b/usb/aidl/default/service.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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "Usb.h"
+
+using ::aidl::android::hardware::usb::Usb;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Usb> usb = ndk::SharedRefBase::make<Usb>();
+
+    const std::string instance = std::string() + Usb::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(usb->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return -1; // Should never be reached
+}
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
new file mode 100644
index 0000000..00a7c93
--- /dev/null
+++ b/usb/aidl/vts/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"],
+}
+
+cc_test {
+    name: "VtsAidlUsbTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsAidlUsbTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.usb-V1-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
new file mode 100644
index 0000000..09cb096
--- /dev/null
+++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Probject
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "UsbAidlTest"
+#include <android-base/logging.h>
+
+#include <aidl/android/hardware/usb/IUsb.h>
+#include <aidl/android/hardware/usb/IUsbCallback.h>
+#include <aidl/android/hardware/usb/BnUsbCallback.h>
+#include <aidl/android/hardware/usb/PortDataRole.h>
+#include <aidl/android/hardware/usb/PortMode.h>
+#include <aidl/android/hardware/usb/PortPowerRole.h>
+#include <aidl/android/hardware/usb/PortRole.h>
+#include <aidl/android/hardware/usb/PortStatus.h>
+#include <aidl/android/hardware/usb/Status.h>
+#include <aidl/Vintf.h>
+#include <aidl/Gtest.h>
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+
+#include <log/log.h>
+#include <stdlib.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#define TIMEOUT_PERIOD 10
+
+using ::aidl::android::hardware::usb::BnUsbCallback;
+using ::aidl::android::hardware::usb::IUsb;
+using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::PortDataRole;
+using ::aidl::android::hardware::usb::PortMode;
+using ::aidl::android::hardware::usb::PortPowerRole;
+using ::aidl::android::hardware::usb::PortRole;
+using ::aidl::android::hardware::usb::PortStatus;
+using ::aidl::android::hardware::usb::Status;
+
+using ::ndk::ScopedAStatus;
+using ::ndk::SpAIBinder;
+using std::vector;
+using std::shared_ptr;
+using std::string;
+
+// The main test class for the USB aidl hal
+class UsbAidlTest : public testing::TestWithParam<std::string> {
+ public:
+  // Callback class for the USB aidl hal.
+  // Usb Hal will call this object upon role switch or port query.
+  class UsbCallback : public BnUsbCallback {
+    UsbAidlTest& parent_;
+    int cookie;
+
+   public:
+    UsbCallback(UsbAidlTest& parent, int cookie)
+        : parent_(parent), cookie(cookie){};
+
+    virtual ~UsbCallback() = default;
+
+    // Callback method for the port status.
+    ScopedAStatus notifyPortStatusChange(const vector<PortStatus>& currentPortStatus,
+                                         Status retval) override {
+      if (retval == Status::SUCCESS && currentPortStatus.size() > 0) {
+        parent_.usb_last_port_status.portName =
+            currentPortStatus[0].portName.c_str();
+        parent_.usb_last_port_status.currentDataRole =
+            currentPortStatus[0].currentDataRole;
+        parent_.usb_last_port_status.currentPowerRole =
+            currentPortStatus[0].currentPowerRole;
+        parent_.usb_last_port_status.currentMode =
+            currentPortStatus[0].currentMode;
+      }
+      parent_.usb_last_cookie = cookie;
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of role switch operation.
+    ScopedAStatus notifyRoleSwitchStatus(const string& /*portName*/, const PortRole& newRole,
+                                         Status retval, int64_t transactionId) override {
+      parent_.usb_last_status = retval;
+      parent_.usb_last_cookie = cookie;
+      parent_.usb_last_port_role = newRole;
+      parent_.usb_role_switch_done = true;
+      parent_.last_transactionId = transactionId;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of enableUsbData operation
+    ScopedAStatus notifyEnableUsbDataStatus(const string& /*portName*/, bool /*enable*/,
+                                            Status /*retval*/, int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.usb_last_cookie = cookie;
+      parent_.enable_usb_data_done = true;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of enableContaminantPresenceDetection
+    ScopedAStatus notifyContaminantEnabledStatus(const string& /*portName*/, bool /*enable*/,
+                                                 Status /*retval*/, int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.usb_last_cookie = cookie;
+      parent_.enable_contaminant_done = true;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of queryPortStatus operation
+    ScopedAStatus notifyQueryPortStatus(const string& /*portName*/, Status /*retval*/,
+                                        int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+  };
+
+  virtual void SetUp() override {
+    ALOGI("Setup");
+    usb = IUsb::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(usb, nullptr);
+
+    usb_cb_2 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 2);
+    ASSERT_NE(usb_cb_2, nullptr);
+    const auto& ret = usb->setCallback(usb_cb_2);
+    ASSERT_TRUE(ret.isOk());
+  }
+
+  virtual void TearDown() override { ALOGI("Teardown"); }
+
+  // Used as a mechanism to inform the test about data/event callback.
+  inline void notify() {
+    std::unique_lock<std::mutex> lock(usb_mtx);
+    usb_count++;
+    usb_cv.notify_one();
+  }
+
+  // Test code calls this function to wait for data/event callback.
+  inline std::cv_status wait() {
+    std::unique_lock<std::mutex> lock(usb_mtx);
+
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (usb_count == 0) {
+      status =
+          usb_cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+      if (status == std::cv_status::timeout) {
+        ALOGI("timeout");
+        return status;
+      }
+    }
+    usb_count--;
+    return status;
+  }
+
+  // USB aidl hal Proxy
+  shared_ptr<IUsb> usb;
+
+  // Callback objects for usb aidl
+  // Methods of these objects are called to notify port status updates.
+  shared_ptr<IUsbCallback> usb_cb_1, usb_cb_2;
+
+  // The last conveyed status of the USB ports.
+  // Stores information of currentt_data_role, power_role for all the USB ports
+  PortStatus usb_last_port_status;
+
+  // Status of the last role switch operation.
+  Status usb_last_status;
+
+  // Port role information of the last role switch operation.
+  PortRole usb_last_port_role;
+
+  // Flag to indicate the invocation of role switch callback.
+  bool usb_role_switch_done;
+
+  // Flag to indicate the invocation of notifyContaminantEnabledStatus callback.
+  bool enable_contaminant_done;
+
+  // Flag to indicate the invocation of notifyEnableUsbDataStatus callback.
+  bool enable_usb_data_done;
+
+  // Stores the cookie of the last invoked usb callback object.
+  int usb_last_cookie;
+
+  // Last transaction ID that was recorded.
+  int64_t last_transactionId;
+  // synchronization primitives to coordinate between main test thread
+  // and the callback thread.
+  std::mutex usb_mtx;
+  std::condition_variable usb_cv;
+  int usb_count = 0;
+};
+
+/*
+ * Test to see if setCallback succeeds.
+ * Callback object is created and registered.
+ */
+TEST_P(UsbAidlTest, setCallback) {
+  ALOGI("UsbAidlTest setCallback start");
+  usb_cb_1 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 1);
+  ASSERT_NE(usb_cb_1, nullptr);
+  const auto& ret = usb->setCallback(usb_cb_1);
+  ASSERT_TRUE(ret.isOk());
+  ALOGI("UsbAidlTest setCallback end");
+}
+
+/*
+ * Check to see if querying type-c
+ * port status succeeds.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, queryPortStatus) {
+  ALOGI("UsbAidlTest queryPortStatus start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+  ALOGI("UsbAidlTest queryPortStatus end: %s", usb_last_port_status.portName.c_str());
+}
+
+/*
+ * Trying to switch a non-existent port should fail.
+ * This test case tried to switch the port with empty
+ * name which is expected to fail.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchEmptyPort) {
+  ALOGI("UsbAidlTest switchEmptyPort start");
+  PortRole role;
+  role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->switchRole("", role, transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(Status::ERROR, usb_last_status);
+  EXPECT_EQ(transactionId, last_transactionId);
+  EXPECT_EQ(2, usb_last_cookie);
+  ALOGI("UsbAidlTest switchEmptyPort end");
+}
+
+/*
+ * Test switching the power role of usb port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, a power role switch
+ * to SOURCE is attempted for the port.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchPowerRole) {
+  ALOGI("UsbAidlTest switchPowerRole start");
+  PortRole role;
+  role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    string portBeingSwitched = usb_last_port_status.portName;
+    ALOGI("switchPower role portname:%s", portBeingSwitched.c_str());
+    usb_role_switch_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           usb_role_switch_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest switchPowerRole end");
+}
+
+/*
+ * Test switching the data role of usb port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, a data role switch
+ * to device is attempted for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchDataRole) {
+  ALOGI("UsbAidlTest switchDataRole start");
+  PortRole role;
+  role.set<PortRole::dataRole>(PortDataRole::DEVICE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    string portBeingSwitched = usb_last_port_status.portName;
+    ALOGI("portname:%s", portBeingSwitched.c_str());
+    usb_role_switch_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           usb_role_switch_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest switchDataRole end");
+}
+
+/*
+ * Test enabling contaminant presence detection of the port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, enabling contaminant detection
+ * is attempted for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, enableContaminantPresenceDetection) {
+  ALOGI("UsbAidlTest enableContaminantPresenceDetection start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    ALOGI("portname:%s", usb_last_port_status.portName.c_str());
+    enable_contaminant_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->enableContaminantPresenceDetection(usb_last_port_status.portName,
+                                                              true, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           enable_contaminant_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest enableContaminantPresenceDetection end");
+}
+
+/*
+ * Test enabling Usb data of the port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, enabling Usb data is attempted
+ * for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, enableUsbData) {
+  ALOGI("UsbAidlTest enableUsbData start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    ALOGI("portname:%s", usb_last_port_status.portName.c_str());
+    enable_usb_data_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->enableUsbData(usb_last_port_status.portName, true, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           enable_usb_data_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest enableUsbData end");
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, UsbAidlTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IUsb::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index acdbdcd..c4140be 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -63,7 +63,6 @@
         "libbinder_random_parcel",
         "libcutils",
         "liblog",
-        "libutils",
         "libvibratorexampleimpl",
     ],
     target: {
@@ -71,12 +70,14 @@
             shared_libs: [
                 "libbinder_ndk",
                 "libbinder",
+                "libutils",
             ],
         },
         host: {
             static_libs: [
                 "libbinder_ndk",
                 "libbinder",
+                "libutils",
             ],
         },
         darwin: {
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 5755ce5..ddc6ee0 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -24,21 +24,23 @@
 namespace hardware {
 namespace vibrator {
 
-static constexpr int32_t kComposeDelayMaxMs = 1000;
-static constexpr int32_t kComposeSizeMax = 256;
-static constexpr int32_t kComposePwleSizeMax = 127;
+static constexpr int32_t COMPOSE_DELAY_MAX_MS = 1000;
+static constexpr int32_t COMPOSE_SIZE_MAX = 256;
+static constexpr int32_t COMPOSE_PWLE_SIZE_MAX = 127;
 
-static constexpr float kResonantFrequency = 150.0;
-static constexpr float kQFactor = 11.0;
+static constexpr float Q_FACTOR = 11.0;
 static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383;
 static constexpr float PWLE_LEVEL_MIN = 0.0;
-static constexpr float PWLE_LEVEL_MAX = 0.98256;
+static constexpr float PWLE_LEVEL_MAX = 1.0;
 static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 1.0;
 static constexpr float PWLE_FREQUENCY_MIN_HZ = 140.0;
+static constexpr float RESONANT_FREQUENCY_HZ = 150.0;
 static constexpr float PWLE_FREQUENCY_MAX_HZ = 160.0;
+static constexpr float PWLE_BW_MAP_SIZE =
+        1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
 
 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
-    LOG(INFO) << "Vibrator reporting capabilities";
+    LOG(VERBOSE) << "Vibrator reporting capabilities";
     *_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
                     IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
                     IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS |
@@ -49,18 +51,18 @@
 }
 
 ndk::ScopedAStatus Vibrator::off() {
-    LOG(INFO) << "Vibrator off";
+    LOG(VERBOSE) << "Vibrator off";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
                                 const std::shared_ptr<IVibratorCallback>& callback) {
-    LOG(INFO) << "Vibrator on for timeoutMs: " << timeoutMs;
+    LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
     if (callback != nullptr) {
         std::thread([=] {
-            LOG(INFO) << "Starting on on another thread";
+            LOG(VERBOSE) << "Starting on on another thread";
             usleep(timeoutMs * 1000);
-            LOG(INFO) << "Notifying on complete";
+            LOG(VERBOSE) << "Notifying on complete";
             if (!callback->onComplete().isOk()) {
                 LOG(ERROR) << "Failed to call onComplete";
             }
@@ -72,7 +74,7 @@
 ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
                                      const std::shared_ptr<IVibratorCallback>& callback,
                                      int32_t* _aidl_return) {
-    LOG(INFO) << "Vibrator perform";
+    LOG(VERBOSE) << "Vibrator perform";
 
     if (effect != Effect::CLICK && effect != Effect::TICK) {
         return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
@@ -86,9 +88,9 @@
 
     if (callback != nullptr) {
         std::thread([=] {
-            LOG(INFO) << "Starting perform on another thread";
+            LOG(VERBOSE) << "Starting perform on another thread";
             usleep(kEffectMillis * 1000);
-            LOG(INFO) << "Notifying perform complete";
+            LOG(VERBOSE) << "Notifying perform complete";
             callback->onComplete();
         }).detach();
     }
@@ -103,7 +105,7 @@
 }
 
 ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
-    LOG(INFO) << "Vibrator set amplitude: " << amplitude;
+    LOG(VERBOSE) << "Vibrator set amplitude: " << amplitude;
     if (amplitude <= 0.0f || amplitude > 1.0f) {
         return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
     }
@@ -111,17 +113,17 @@
 }
 
 ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
-    LOG(INFO) << "Vibrator set external control: " << enabled;
+    LOG(VERBOSE) << "Vibrator set external control: " << enabled;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* maxDelayMs) {
-    *maxDelayMs = kComposeDelayMaxMs;
+    *maxDelayMs = COMPOSE_DELAY_MAX_MS;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
-    *maxSize = kComposeSizeMax;
+    *maxSize = COMPOSE_SIZE_MAX;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -153,7 +155,7 @@
 
 ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
                                      const std::shared_ptr<IVibratorCallback>& callback) {
-    if (composite.size() > kComposeSizeMax) {
+    if (composite.size() > COMPOSE_SIZE_MAX) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
@@ -161,7 +163,7 @@
     getSupportedPrimitives(&supported);
 
     for (auto& e : composite) {
-        if (e.delayMs > kComposeDelayMaxMs) {
+        if (e.delayMs > COMPOSE_DELAY_MAX_MS) {
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         if (e.scale < 0.0f || e.scale > 1.0f) {
@@ -173,14 +175,14 @@
     }
 
     std::thread([=] {
-        LOG(INFO) << "Starting compose on another thread";
+        LOG(VERBOSE) << "Starting compose on another thread";
 
         for (auto& e : composite) {
             if (e.delayMs) {
                 usleep(e.delayMs * 1000);
             }
-            LOG(INFO) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
-                      << e.scale;
+            LOG(VERBOSE) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
+                         << e.scale;
 
             int32_t durationMs;
             getPrimitiveDuration(e.primitive, &durationMs);
@@ -188,7 +190,7 @@
         }
 
         if (callback != nullptr) {
-            LOG(INFO) << "Notifying perform complete";
+            LOG(VERBOSE) << "Notifying perform complete";
             callback->onComplete();
         }
     }).detach();
@@ -207,24 +209,24 @@
     if (std::find(effects.begin(), effects.end(), effect) == effects.end()) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
     } else {
-        LOG(INFO) << "Enabling always-on ID " << id << " with " << toString(effect) << "/"
-                  << toString(strength);
+        LOG(VERBOSE) << "Enabling always-on ID " << id << " with " << toString(effect) << "/"
+                     << toString(strength);
         return ndk::ScopedAStatus::ok();
     }
 }
 
 ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id) {
-    LOG(INFO) << "Disabling always-on ID " << id;
+    LOG(VERBOSE) << "Disabling always-on ID " << id;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
-    *resonantFreqHz = kResonantFrequency;
+    *resonantFreqHz = RESONANT_FREQUENCY_HZ;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
-    *qFactor = kQFactor;
+    *qFactor = Q_FACTOR;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -239,11 +241,26 @@
 }
 
 ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) {
-    // A valid array should be of size:
-    //     (PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ
-    *_aidl_return = {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10,
-                     0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20};
-    return ndk::ScopedAStatus::ok();
+    // The output BandwidthAmplitudeMap will be as below and the maximum
+    // amplitude 1.0 will be set on RESONANT_FREQUENCY_HZ
+    // {0.9, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1, 0.99, 0.98, 0.97,
+    // 0.96, 0.95, 0.94, 0.93, 0.92, 0.91, 0.9}
+    int32_t capabilities = 0;
+    int halfMapSize = PWLE_BW_MAP_SIZE / 2;
+    Vibrator::getCapabilities(&capabilities);
+    if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+        std::vector<float> bandwidthAmplitudeMap(PWLE_BW_MAP_SIZE, PWLE_LEVEL_MAX);
+        for (int i = 0; i < halfMapSize; ++i) {
+            bandwidthAmplitudeMap[halfMapSize + i + 1] =
+                    bandwidthAmplitudeMap[halfMapSize + i] - 0.01;
+            bandwidthAmplitudeMap[halfMapSize - i - 1] =
+                    bandwidthAmplitudeMap[halfMapSize - i] - 0.01;
+        }
+        *_aidl_return = bandwidthAmplitudeMap;
+        return ndk::ScopedAStatus::ok();
+    } else {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
 }
 
 ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
@@ -252,7 +269,7 @@
 }
 
 ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
-    *maxSize = kComposePwleSizeMax;
+    *maxSize = COMPOSE_PWLE_SIZE_MAX;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -380,10 +397,10 @@
     }
 
     std::thread([=] {
-        LOG(INFO) << "Starting composePwle on another thread";
+        LOG(VERBOSE) << "Starting composePwle on another thread";
         usleep(totalDuration * 1000);
         if (callback != nullptr) {
-            LOG(INFO) << "Notifying compose PWLE complete";
+            LOG(VERBOSE) << "Notifying compose PWLE complete";
             callback->onComplete();
         }
     }).detach();
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 53f8c0e..5251529 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -167,9 +167,9 @@
         EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
     }
 
-    float freqMaximumHz =
-        (bandwidthAmplitudeMap.size() * getFrequencyResolutionHz(vibrator, capabilities)) +
-        getFrequencyMinimumHz(vibrator, capabilities);
+    float freqMaximumHz = ((bandwidthAmplitudeMap.size() - 1) *
+                           getFrequencyResolutionHz(vibrator, capabilities)) +
+                          getFrequencyMinimumHz(vibrator, capabilities);
     return freqMaximumHz;
 }
 
@@ -196,7 +196,7 @@
     active.startFrequency = frequencyHz;
     active.endAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2;
     active.endFrequency = frequencyHz;
-    active.duration = 1000;
+    vibrator->getPwlePrimitiveDurationMax(&(active.duration));
 
     return active;
 }
@@ -756,7 +756,9 @@
     std::future<void> completionFuture{completionPromise.get_future()};
     sp<CompletionCallback> callback =
         new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
-    uint32_t durationMs = 2100;  // Sum of 2 active and 1 braking below
+    int32_t segmentDurationMaxMs;
+    vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
+    uint32_t durationMs = segmentDurationMaxMs * 2 + 100;  // Sum of 2 active and 1 braking below
     //TODO(b/187207798): revert back to conservative timeout values once
     //latencies have been fixed
     std::chrono::milliseconds timeout{durationMs * 4};
@@ -860,7 +862,7 @@
     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
         ActivePwle active = composeValidActivePwle(vibrator, capabilities);
 
-        int segmentDurationMaxMs;
+        int32_t segmentDurationMaxMs;
         vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
         active.duration = segmentDurationMaxMs + 10;  // Segment duration greater than allowed