Merge "Backport VTS fixes to previous test versions" into udc-dev
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
index 9914460..b71ab29 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
@@ -1 +1 @@
-504db4349f884424a8acc3f2fc0f6bb74dbfcdf0
+34b618a587cb9977ee0cd13b173e699d2dcdb320
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
index 82dae97..115da1d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
@@ -50,8 +50,8 @@
   const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
   const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
   const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
   @VintfStability
   parcelable Identity {
     android.media.audio.common.AudioUuid type;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
index 82dae97..115da1d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
@@ -50,8 +50,8 @@
   const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
   const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
   const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
   @VintfStability
   parcelable Identity {
     android.media.audio.common.AudioUuid type;
diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
index 2fbc401..b152f76 100644
--- a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
@@ -96,11 +96,11 @@
     /**
      * UUID for visualizer effect type.
      */
-    const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
+    const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
     /**
      * UUID for Volume effect type.
      */
-    const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
+    const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
 
     /**
      * This structure completely identifies an effect implementation.
diff --git a/audio/aidl/sounddose/default/Android.bp b/audio/aidl/sounddose/default/Android.bp
deleted file mode 100644
index bd770fa..0000000
--- a/audio/aidl/sounddose/default/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_defaults {
-    name: "aidlsounddoseservice_defaults",
-    vendor: true,
-    header_libs: [
-        "libsounddoseaidl_headers",
-    ],
-}
-
-cc_library {
-    name: "libsounddoseserviceexampleimpl",
-    defaults: [
-        "aidlsounddoseservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_core_sounddose_ndk_shared",
-        "latest_android_hardware_audio_sounddose_ndk_shared",
-    ],
-    export_include_dirs: ["include"],
-    srcs: [
-        "SoundDoseFactory.cpp",
-    ],
-    shared_libs: [
-        "libaudioservicesounddoseimpl",
-        "libbase",
-        "libbinder_ndk",
-    ],
-
-    visibility: [
-        "//hardware/interfaces/audio/common/all-versions/default/service",
-    ],
-}
-
-cc_library_headers {
-    name: "libsounddoseaidl_headers",
-    export_include_dirs: ["include"],
-    vendor_available: true,
-    host_supported: true,
-}
diff --git a/audio/aidl/sounddose/default/SoundDoseFactory.cpp b/audio/aidl/sounddose/default/SoundDoseFactory.cpp
deleted file mode 100644
index 83a592b..0000000
--- a/audio/aidl/sounddose/default/SoundDoseFactory.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "AHAL_SoundDoseFactory"
-
-#include "SoundDoseFactory.h"
-
-#include <android-base/logging.h>
-#include <core-impl/SoundDose.h>
-
-namespace aidl::android::hardware::audio::sounddose {
-
-using ::aidl::android::hardware::audio::core::sounddose::SoundDose;
-
-ndk::ScopedAStatus SoundDoseFactory::getSoundDose(const std::string& in_module,
-                                                  std::shared_ptr<ISoundDose>* _aidl_return) {
-    auto soundDoseIt = mSoundDoseBinderMap.find(in_module);
-    if (soundDoseIt != mSoundDoseBinderMap.end()) {
-        *_aidl_return = ISoundDose::fromBinder(soundDoseIt->second);
-
-        LOG(DEBUG) << __func__
-                   << ": returning cached instance of ISoundDose: " << _aidl_return->get()
-                   << " for module " << in_module;
-        return ndk::ScopedAStatus::ok();
-    }
-
-    auto soundDose = ndk::SharedRefBase::make<SoundDose>();
-    mSoundDoseBinderMap[in_module] = soundDose->asBinder();
-    *_aidl_return = soundDose;
-
-    LOG(DEBUG) << __func__ << ": returning new instance of ISoundDose: " << _aidl_return->get()
-               << " for module " << in_module;
-    return ndk::ScopedAStatus::ok();
-}
-
-}  // namespace aidl::android::hardware::audio::sounddose
diff --git a/audio/aidl/sounddose/default/include/SoundDoseFactory.h b/audio/aidl/sounddose/default/include/SoundDoseFactory.h
deleted file mode 100644
index ced4291..0000000
--- a/audio/aidl/sounddose/default/include/SoundDoseFactory.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
-#include <aidl/android/hardware/audio/sounddose/BnSoundDoseFactory.h>
-#include <android/binder_interface_utils.h>
-
-#include <unordered_map>
-
-namespace aidl::android::hardware::audio::sounddose {
-
-using ::aidl::android::hardware::audio::core::sounddose::ISoundDose;
-
-class SoundDoseFactory : public BnSoundDoseFactory {
-  public:
-    ndk::ScopedAStatus getSoundDose(const std::string& module,
-                                    std::shared_ptr<ISoundDose>* _aidl_return) override;
-
-  private:
-    std::unordered_map<std::string, ndk::SpAIBinder> mSoundDoseBinderMap;
-};
-
-}  // namespace aidl::android::hardware::audio::sounddose
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 2fcfb23..d513062 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -38,13 +38,11 @@
     name: "android.hardware.audio.service",
 
     init_rc: ["android.hardware.audio.service.rc"],
-    vintf_fragments: ["android.hardware.audio.sounddose-aidl.xml"],
     relative_install_path: "hw",
     vendor: true,
 
     defaults: [
         "android_hardware_audio_config_defaults",
-        "latest_android_hardware_audio_sounddose_ndk_shared",
     ],
 
     srcs: ["service.cpp"],
@@ -56,7 +54,6 @@
     ],
 
     shared_libs: [
-        "//hardware/interfaces/audio/aidl/sounddose/default:libsounddoseserviceexampleimpl",
         "libcutils",
         "libbinder",
         "libbinder_ndk",
diff --git a/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml b/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml
deleted file mode 100644
index a297bfb..0000000
--- a/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
-  <hal format="aidl">
-    <name>android.hardware.audio.sounddose</name>
-    <version>1</version>
-    <fqname>ISoundDoseFactory/default</fqname>
-  </hal>
-</manifest>
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 7b5a932..1557a95 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -20,10 +20,6 @@
 #include <string>
 #include <vector>
 
-#include <SoundDoseFactory.h>
-#include <android-base/logging.h>
-#include <android/binder_ibinder_platform.h>
-#include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <binder/ProcessState.h>
 #include <cutils/properties.h>
@@ -37,8 +33,6 @@
 
 using InterfacesList = std::vector<std::string>;
 
-using aidl::android::hardware::audio::sounddose::SoundDoseFactory;
-
 /** Try to register the provided factories in the provided order.
  *  If any registers successfully, do not register any other and return true.
  *  If all fail, return false.
@@ -144,6 +138,10 @@
             "android.hardware.bluetooth.audio-impl",
             "createIBluetoothAudioProviderFactory",
         },
+        {
+            "android.hardware.audio.sounddose-vendor-impl",
+            "createISoundDoseFactory",
+        },
     };
     // clang-format on
 
@@ -171,13 +169,5 @@
         }
     }
 
-    // Register ISoundDoseFactory interface as a workaround for using the audio AIDL HAL
-    auto soundDoseDefault = ndk::SharedRefBase::make<SoundDoseFactory>();
-    const std::string soundDoseDefaultName =
-            std::string() + SoundDoseFactory::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(soundDoseDefault->asBinder().get(),
-                                                        soundDoseDefaultName.c_str());
-    CHECK_EQ(STATUS_OK, status);
-
     joinRpcThreadpool();
 }
diff --git a/automotive/ivn_android_device/impl/default/Android.bp b/automotive/ivn_android_device/impl/default/Android.bp
new file mode 100644
index 0000000..98c1f58
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "IvnAndroidDeviceService",
+    vendor_available: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/IvnAndroidDeviceService.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.ivn-V1-ndk",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.automotive.ivn@V1-default-service",
+    vendor: true,
+    relative_install_path: "hw",
+    local_include_dirs: ["include"],
+    srcs: ["src/IvnAndroidDeviceImpl.cpp"],
+    whole_static_libs: ["IvnAndroidDeviceService"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+    required: ["Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON"],
+    vintf_fragments: ["ivn-default-service.xml"],
+    init_rc: ["ivn-default-service.rc"],
+}
diff --git a/automotive/ivn_android_device/impl/default/config/Android.bp b/automotive/ivn_android_device/impl/default/config/Android.bp
new file mode 100644
index 0000000..03c4d1b
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/config/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "IvnAndroidDeviceServiceDefaultConfig_Json",
+    srcs: ["DefaultConfig.json"],
+}
+
+prebuilt_etc {
+    name: "Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON",
+    filename_from_src: true,
+    src: "DefaultConfig.json",
+    sub_dir: "automotive/IvnConfig/",
+    vendor: true,
+}
diff --git a/automotive/ivn_android_device/impl/default/config/DefaultConfig.json b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json
new file mode 100644
index 0000000..45663e2
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json
@@ -0,0 +1,61 @@
+{
+    "MyDeviceId": 0,
+    "Devices": [
+        {
+            "DeviceId": 0,
+            "OccupantZones": [
+                {
+                    "ZoneId": 0,
+                    "OccupantType": "DRIVER",
+                    "Seat": 1,
+                    "Comments": "Occupant zone for driver and FRONT_LEFT seat"
+                },
+                {
+                    "ZoneId": 1,
+                    "OccupantType": "FRONT_PASSENGER",
+                    "Seat": 4,
+                    "Comments": "Occupant zone for FRONT_RIGHT passenger"
+                }
+            ],
+            "EndpointInfo": {
+                "IpAddress": "10.10.10.1",
+                "PortNumber": 1234,
+                "BrandName": "MyBrand",
+                "DeviceName": "MyDevice",
+                "ProductName": "MyProduct",
+                "ManufacturerName": "MyCompany",
+                "ModelName": "MyModel",
+                "SerialNumber": "Serial1234"
+            },
+            "Comments": "Device for front row"
+        },
+        {
+            "DeviceId": 1,
+            "OccupantZones": [
+                {
+                    "ZoneId": 2,
+                    "OccupantType": "REAR_PASSENGER",
+                    "Seat": 16
+                },
+                {
+                    "ZoneId": 3,
+                    "OccupantType": "REAR_PASSENGER",
+                    "Seat": 64
+                }
+            ],
+            "EndpointInfo": {
+                "IpAddress": "10.10.10.2",
+                "PortNumber": 2345,
+                "BrandName": "MyBrand",
+                "DeviceName": "MyDevice",
+                "ProductName": "MyProduct",
+                "ManufacturerName": "MyCompany",
+                "ModelName": "MyModel",
+                "SerialNumber": "Serial2345"
+            },
+            "Comments": "Device for back row"
+        }
+    ],
+    "Comment":
+            "This simulates a vehicle with two Android devices, one for front row, one for back row"
+}
diff --git a/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h
new file mode 100644
index 0000000..c0cc9fe
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/ivn/BnIvnAndroidDevice.h>
+#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h>
+#include <android/binder_auto_utils.h>
+#include <vector>
+
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+struct DeviceInfo {
+    std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo> occupantZones;
+    aidl::android::hardware::automotive::ivn::EndpointInfo endpointInfo;
+};
+
+class IvnAndroidDeviceService
+    : public aidl::android::hardware::automotive::ivn::BnIvnAndroidDevice {
+  public:
+    explicit IvnAndroidDeviceService(std::string_view configPath);
+
+    // Initialize the service, returns true on success.
+    bool init();
+
+    ndk::ScopedAStatus getMyDeviceId(int* deviceId) override;
+
+    ndk::ScopedAStatus getOtherDeviceIds(std::vector<int>* deviceIds) override;
+
+    ndk::ScopedAStatus getDeviceIdForOccupantZone(int zoneId, int* deviceId) override;
+
+    ndk::ScopedAStatus getOccupantZonesForDevice(
+            int androidDeviceId,
+            std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo>* occupantZones)
+            override;
+
+    ndk::ScopedAStatus getMyEndpointInfo(
+            aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override;
+
+    ndk::ScopedAStatus getEndpointInfoForDevice(
+            int androidDeviceId,
+            aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override;
+
+  private:
+    int mMyDeviceId;
+    std::unordered_map<int, DeviceInfo> mDeviceInfoById;
+    std::string_view mConfigPath;
+};
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.rc b/automotive/ivn_android_device/impl/default/ivn-default-service.rc
new file mode 100644
index 0000000..070b259
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/ivn-default-service.rc
@@ -0,0 +1,4 @@
+service vendor.ivn-default /vendor/bin/hw/android.hardware.automotive.ivn@V1-default-service
+    class hal
+    user vehicle_network
+    group system inet
diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.xml b/automotive/ivn_android_device/impl/default/ivn-default-service.xml
new file mode 100644
index 0000000..481bc0a
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/ivn-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.ivn</name>
+        <version>1</version>
+        <fqname>IIvnAndroidDevice/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp
new file mode 100644
index 0000000..fdf6776
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "IvnAndroidDeviceImpl"
+
+#include "IvnAndroidDeviceService.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <stdlib.h>
+
+constexpr char SERVICE_NAME[] = "android.hardware.automotive.ivn.IIvnAndroidDevice/default";
+constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/IvnConfig/DefaultConfig.json";
+
+int main(int /* argc */, char* /* argv */[]) {
+    LOG(INFO) << "Registering IvnAndroidDeviceService as service...";
+    auto service =
+            ndk::SharedRefBase::make<android::hardware::automotive::ivn::IvnAndroidDeviceService>(
+                    DEFAULT_CONFIG_DIR);
+    if (!service->init()) {
+        LOG(ERROR) << "Failed to init IvnAndroidDeviceService";
+        exit(1);
+    }
+
+    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
+    if (err != EX_NONE) {
+        LOG(ERROR) << "Failed to register IvnAndroidDeviceService service, exception: " << err;
+        exit(1);
+    }
+
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
+        LOG(ERROR) << "Failed to set thread pool max thread count";
+        exit(1);
+    }
+    ABinderProcess_startThreadPool();
+
+    LOG(INFO) << "IvnAndroidDeviceService Ready";
+
+    ABinderProcess_joinThreadPool();
+
+    LOG(ERROR) << "IvnAndroidDeviceService init failed! Should not reach here";
+
+    return 0;
+}
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
new file mode 100644
index 0000000..71454d5
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "IvnAndroidDeviceService.h"
+
+#include <aidl/android/hardware/automotive/ivn/ConnectProtocol.h>
+#include <aidl/android/hardware/automotive/ivn/HardwareIdentifiers.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantType.h>
+#include <android-base/logging.h>
+#include <android/binder_status.h>
+#include <json/json.h>
+
+#include <fstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::ivn::ConnectProtocol;
+using ::aidl::android::hardware::automotive::ivn::EndpointInfo;
+using ::aidl::android::hardware::automotive::ivn::HardwareIdentifiers;
+using ::aidl::android::hardware::automotive::ivn::OccupantType;
+using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo;
+using ::ndk::ScopedAStatus;
+
+constexpr int IVN_ERROR_GENERIC = -1;
+
+}  // namespace
+
+IvnAndroidDeviceService::IvnAndroidDeviceService(std::string_view configPath) {
+    mConfigPath = configPath;
+}
+
+bool IvnAndroidDeviceService::init() {
+    std::ifstream configStream(mConfigPath);
+    if (!configStream) {
+        LOG(ERROR) << "couldn't open " << mConfigPath << " for parsing.";
+        return false;
+    }
+    Json::CharReaderBuilder builder;
+    Json::Value root;
+    std::string errs;
+    if (!Json::parseFromStream(builder, configStream, &root, &errs)) {
+        LOG(ERROR) << "Failed to parse config JSON stream, error: " << errs;
+        return false;
+    }
+    if (!root.isObject()) {
+        LOG(ERROR) << "Root must be an object";
+        return false;
+    }
+    if (!root.isMember("MyDeviceId")) {
+        LOG(ERROR) << "Must contain 'MyDeviceId' field";
+        return false;
+    }
+    mMyDeviceId = root["MyDeviceId"].asInt();
+    if (!root.isMember("Devices") || !root["Devices"].isArray()) {
+        LOG(ERROR) << "Must contain 'Devices' field as array";
+        return false;
+    }
+    Json::Value& devices = root["Devices"];
+    for (unsigned int i = 0; i < devices.size(); i++) {
+        Json::Value& device = devices[i];
+        int deviceId = device["DeviceId"].asInt();
+        DeviceInfo deviceInfo = {};
+        Json::Value& occupantZones = device["OccupantZones"];
+        for (unsigned int j = 0; j < occupantZones.size(); j++) {
+            Json::Value& occupantZone = occupantZones[j];
+            int zoneId = occupantZone["ZoneId"].asInt();
+            std::string occupantTypeStr = occupantZone["OccupantType"].asString();
+            int seat = occupantZone["Seat"].asInt();
+            OccupantType occupantType;
+            if (occupantTypeStr == "DRIVER") {
+                occupantType = OccupantType::DRIVER;
+            } else if (occupantTypeStr == "FRONT_PASSENGER") {
+                occupantType = OccupantType::FRONT_PASSENGER;
+            } else if (occupantTypeStr == "REAR_PASSENGER") {
+                occupantType = OccupantType::REAR_PASSENGER;
+            } else {
+                LOG(ERROR) << "Unknown occupant type: " << occupantTypeStr;
+                return false;
+            }
+            OccupantZoneInfo occupantZoneInfo = {
+                    .zoneId = zoneId, .occupantType = occupantType, .seat = seat};
+            deviceInfo.occupantZones.push_back(std::move(occupantZoneInfo));
+        }
+        Json::Value& ep = device["EndpointInfo"];
+        EndpointInfo endpointInfo = {};
+        endpointInfo.connectProtocol = ConnectProtocol::TCP_IP;
+        endpointInfo.ipAddress = ep["IpAddress"].asString();
+        endpointInfo.portNumber = ep["PortNumber"].asInt();
+        HardwareIdentifiers hardwareId = {};
+        if (ep.isMember("BrandName")) {
+            hardwareId.brandName = ep["BrandName"].asString();
+        }
+        if (ep.isMember("DeviceName")) {
+            hardwareId.deviceName = ep["DeviceName"].asString();
+        }
+        if (ep.isMember("ProductName")) {
+            hardwareId.productName = ep["ProductName"].asString();
+        }
+        if (ep.isMember("ManufacturerName")) {
+            hardwareId.manufacturerName = ep["ManufacturerName"].asString();
+        }
+        if (ep.isMember("ModelName")) {
+            hardwareId.modelName = ep["ModelName"].asString();
+        }
+        if (ep.isMember("SerialNumber")) {
+            hardwareId.serialNumber = ep["SerialNumber"].asString();
+        }
+        endpointInfo.hardwareId = hardwareId;
+        deviceInfo.endpointInfo = endpointInfo;
+        mDeviceInfoById[deviceId] = deviceInfo;
+    }
+    if (mDeviceInfoById.find(mMyDeviceId) == mDeviceInfoById.end()) {
+        LOG(ERROR) << "My device ID is not in the device info list";
+        return false;
+    }
+    return true;
+}
+
+ScopedAStatus IvnAndroidDeviceService::getMyDeviceId(int* deviceId) {
+    *deviceId = mMyDeviceId;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getOtherDeviceIds(std::vector<int>* deviceIds) {
+    deviceIds->clear();
+    for (const auto& [deviceId, _] : mDeviceInfoById) {
+        if (deviceId == mMyDeviceId) {
+            continue;
+        }
+        deviceIds->push_back(deviceId);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getDeviceIdForOccupantZone(int zoneId, int* outDeviceId) {
+    for (const auto& [deviceId, deviceInfo] : mDeviceInfoById) {
+        for (const auto& occupantZoneInfo : deviceInfo.occupantZones) {
+            if (occupantZoneInfo.zoneId == zoneId) {
+                *outDeviceId = deviceId;
+                return ScopedAStatus::ok();
+            }
+        }
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                              "Occupant zone not found");
+}
+
+ScopedAStatus IvnAndroidDeviceService::getOccupantZonesForDevice(
+        int androidDeviceId, std::vector<OccupantZoneInfo>* occupantZones) {
+    if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                                  "Android device ID not found");
+    }
+    for (const auto& occupantZoneInfo : mDeviceInfoById[androidDeviceId].occupantZones) {
+        occupantZones->push_back(occupantZoneInfo);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getMyEndpointInfo(EndpointInfo* endpointInfo) {
+    *endpointInfo = mDeviceInfoById[mMyDeviceId].endpointInfo;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getEndpointInfoForDevice(int androidDeviceId,
+                                                                EndpointInfo* endpointInfo) {
+    if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                                  "Android device ID not found");
+    }
+    *endpointInfo = mDeviceInfoById[androidDeviceId].endpointInfo;
+    return ScopedAStatus::ok();
+}
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/ivn_android_device/impl/default/test/Android.bp b/automotive/ivn_android_device/impl/default/test/Android.bp
new file mode 100644
index 0000000..a100575
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/test/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "IvnAndroidDeviceServiceUnitTest",
+    vendor: true,
+    srcs: ["*.cpp"],
+    whole_static_libs: [
+        "IvnAndroidDeviceService",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    data: [
+        ":IvnAndroidDeviceServiceDefaultConfig_Json",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp
new file mode 100644
index 0000000..bc8e69f
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "IvnAndroidDeviceService.h"
+
+#include <aidl/android/hardware/automotive/ivn/OccupantType.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h>
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+using ::aidl::android::hardware::automotive::ivn::OccupantType;
+using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo;
+using ::ndk::ScopedAStatus;
+
+class IvnAndroidDeviceServiceUnitTest : public ::testing::Test {
+  public:
+    virtual void SetUp() override {
+        mService = ndk::SharedRefBase::make<IvnAndroidDeviceService>(
+                android::base::GetExecutableDirectory() + "/DefaultConfig.json");
+        mService->init();
+    }
+
+    std::shared_ptr<IvnAndroidDeviceService> mService;
+};
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetMyDeviceId) {
+    int deviceId = -1;
+
+    ScopedAStatus status = mService->getMyDeviceId(&deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_EQ(deviceId, 0);
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOtherDeviceIds) {
+    std::vector<int> deviceIds;
+
+    ScopedAStatus status = mService->getOtherDeviceIds(&deviceIds);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_EQ(deviceIds, std::vector<int>({1}));
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetDeviceIdForOccupantZone) {
+    int deviceId = -1;
+
+    ScopedAStatus status = mService->getDeviceIdForOccupantZone(/*zoneId=*/0, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 0);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/1, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 0);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/2, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 1);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/3, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 1);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/4, &deviceId);
+
+    ASSERT_FALSE(status.isOk());
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOccupantZonesForDevice) {
+    std::vector<OccupantZoneInfo> occupantZones;
+
+    ScopedAStatus status =
+            mService->getOccupantZonesForDevice(/*androidDeviceId=*/0, &occupantZones);
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(occupantZones.size(), 2);
+    if (occupantZones.size() == 2) {
+        EXPECT_EQ(occupantZones[0].zoneId, 0);
+        EXPECT_EQ(occupantZones[0].occupantType, OccupantType::DRIVER);
+        EXPECT_EQ(occupantZones[0].seat, 1);
+        EXPECT_EQ(occupantZones[1].zoneId, 1);
+        EXPECT_EQ(occupantZones[1].occupantType, OccupantType::FRONT_PASSENGER);
+        EXPECT_EQ(occupantZones[1].seat, 4);
+    }
+}
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index ce3a840..6dca41f 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -4629,9 +4629,7 @@
     /**
      * Lane Centering Assist (LCA) commands.
      *
-     * Commands to activate and suspend LCA. They are only valid when LANE_CENTERING_ASSIST_ENABLED
-     * = true. Otherwise, these commands must return StatusCode#NOT_AVAILABLE or
-     * StatusCode#NOT_AVAILABLE_DISABLED.
+     * Commands to activate and suspend LCA.
      *
      * When the command ACTIVATE from LaneCenteringAssistCommmand is sent,
      * LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATION_REQUESTED.
@@ -4643,6 +4641,14 @@
      * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
      * all enum values of LaneCenteringAssistCommand are supported.
      *
+     * When this property is not available because LCA is disabled (i.e.
+     * LANE_CENTERING_ASSIST_ENABLED is false), this property must return
+     * StatusCode#NOT_AVAILABLE_DISABLED. If LANE_CENTERING_ASSIST_STATE is implemented and the
+     * state is set to an ErrorState value, then this property must return a StatusCode that aligns
+     * with the ErrorState value. For example, if LANE_CENTERING_ASSIST_STATE is set to
+     * ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @data_enum LaneCenteringAssistCommmand
@@ -4794,7 +4800,11 @@
      * this property must return StatusCode#INVALID_ARG.
      *
      * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
-     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
@@ -4813,7 +4823,11 @@
      * The minFloatValue represents the lower bound of the target speed.
      *
      * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
-     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
@@ -4836,7 +4850,11 @@
      * writable.
      *
      * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
-     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
      *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
@@ -4865,7 +4883,11 @@
      * StatusCode.NOT_AVAILABLE.
      *
      * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
-     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
index 6ed8e7d..f18da55 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.cpp
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -85,7 +85,7 @@
     // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
     // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
     // by definition the empty string "" is a substring of any string).
-    return !isDsDsEnabled() && !isTsTsEnabled();
+    return !isDsDsEnabled() && !isTsTsEnabled() && !isDsDaEnabled();
 }
 
 bool isDsDsEnabled() {
@@ -125,8 +125,8 @@
             ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
             return false;
         }
-    } else if (isDsDsEnabled()) {
-        // Device is configured as DSDS.
+    } else if (isDsDsEnabled() || isDsDaEnabled()) {
+        // Device is configured as DSDS or DSDA.
         if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
             !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME)) {
             ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 461357d..2a4cba1 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -134,6 +134,10 @@
      *        are marked (see the definition of PublicKey in the MacedPublicKey structure) to
      *        prevent them from being confused with production keys.
      *
+     *        This parameter has been deprecated since version 3 of the HAL and will always be
+     *        false. From v3, if this parameter is true, the method must raise a
+     *        ServiceSpecificException with an error of code of STATUS_REMOVED.
+     *
      * @param out MacedPublicKey macedPublicKey contains the public key of the generated key pair,
      *        MACed so that generateCertificateRequest can easily verify, without the
      *        privateKeyHandle, that the contained public key is for remote certification.
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 94bfbb4..8906543 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -47,7 +47,11 @@
 namespace {
 
 constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
+
+constexpr int32_t VERSION_WITHOUT_EEK = 3;
 constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
+constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
+constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
 
 constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
 constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
@@ -226,21 +230,13 @@
     RpcHardwareInfo hwInfo;
     ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
 
-    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
-    // First check for the implementations that supports only IRPC V3+.
-    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(false, {}, {}, {}, &deviceInfo,
-                                                                 &protectedData, &keysToSignMac);
-        if (!status.isOk() &&
-            (status.getServiceSpecificError() == BnRemotelyProvisionedComponent::STATUS_REMOVED)) {
-            ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
-                    << "Invalid curve: " << hwInfo.supportedEekCurve;
-            return;
-        }
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
+        ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
+                << "Invalid curve: " << hwInfo.supportedEekCurve;
+        return;
     }
+
+    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
     ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
             << "Invalid curve: " << hwInfo.supportedEekCurve;
 }
@@ -264,7 +260,7 @@
  * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
  */
 TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
-    if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
+    if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
         return;
     }
 
@@ -365,6 +361,13 @@
     bytevec privateKeyBlob;
     bool testMode = true;
     auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
+
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
+        ASSERT_FALSE(status.isOk());
+        EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+        return;
+    }
+
     ASSERT_TRUE(status.isOk());
     check_maced_pubkey(macedPubKey, testMode, nullptr);
 }
@@ -410,7 +413,7 @@
         CertificateRequestTestBase::SetUp();
         ASSERT_FALSE(HasFatalFailure());
 
-        if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
+        if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
             GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
                          << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
         }
@@ -688,7 +691,7 @@
         CertificateRequestTestBase::SetUp();
         ASSERT_FALSE(HasFatalFailure());
 
-        if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
+        if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
             GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
                          << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
         }
@@ -802,23 +805,23 @@
 }
 
 /**
- * Generate a non-empty certificate request in prod mode, with test keys.  Must fail with
- * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
+ * Call generateCertificateRequest(). Make sure it's removed.
  */
-TEST_P(CertificateRequestV2Test, NonEmptyRequest_testKeyInProdCert) {
-    generateKeys(true /* testMode */, 1 /* numKeys */);
-
-    bytevec csr;
-    auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
-    ASSERT_EQ(status.getServiceSpecificError(),
-              BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
 }
 
 /**
- * Call generateCertificateRequest(). Make sure it's removed.
+ * Call generateCertificateRequest() in test mode. Make sure it's removed.
  */
-TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed) {
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
     bytevec keysToSignMac;
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index 7eeab68..f2cb3f6 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -64,9 +64,9 @@
 
 void initializeService() {
     if (SupplicantAidlTestUtils::useAidlService()) {
-        SupplicantAidlTestUtils::stopSupplicantService();
+        SupplicantAidlTestUtils::initializeService();
     } else {
-        SupplicantLegacyTestUtils::stopSupplicantService();
+        SupplicantLegacyTestUtils::initializeService();
     }
 }