Merge "Update setNullCipherAndIntegrityEnabled API."
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index ef51361..e69306e 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -112,6 +112,7 @@
         "android/hardware/audio/core/AudioMode.aidl",
         "android/hardware/audio/core/AudioPatch.aidl",
         "android/hardware/audio/core/AudioRoute.aidl",
+        "android/hardware/audio/core/IBluetooth.aidl",
         "android/hardware/audio/core/IConfig.aidl",
         "android/hardware/audio/core/IModule.aidl",
         "android/hardware/audio/core/IStreamCallback.aidl",
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..289c0c2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetooth {
+  android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
+  android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable ScoConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Boolean isNrecEnabled;
+    android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
+    @nullable @utf8InCpp String debugName;
+    @VintfStability
+    enum Mode {
+      UNSPECIFIED = 0,
+      SCO = 1,
+      SCO_WB = 2,
+      SCO_SWB = 3,
+    }
+  }
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable HfpConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Int sampleRate;
+    @nullable android.media.audio.common.Float volume;
+    const int VOLUME_MIN = 0;
+    const int VOLUME_MAX = 1;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index a029d43..4486b66 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -36,6 +36,7 @@
 interface IModule {
   void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
   @nullable android.hardware.audio.core.ITelephony getTelephony();
+  @nullable android.hardware.audio.core.IBluetooth getBluetooth();
   android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
   void disconnectExternalDevice(int portId);
   android.hardware.audio.core.AudioPatch[] getAudioPatches();
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
index a8c58c1..77063df 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
@@ -36,4 +36,21 @@
 interface ITelephony {
   android.hardware.audio.core.AudioMode[] getSupportedAudioModes();
   void switchAudioMode(android.hardware.audio.core.AudioMode mode);
+  android.hardware.audio.core.ITelephony.TelecomConfig setTelecomConfig(in android.hardware.audio.core.ITelephony.TelecomConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable TelecomConfig {
+    @nullable android.media.audio.common.Float voiceVolume;
+    android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode ttyMode = android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode.UNSPECIFIED;
+    @nullable android.media.audio.common.Boolean isHacEnabled;
+    const int VOICE_VOLUME_MIN = 0;
+    const int VOICE_VOLUME_MAX = 1;
+    @Backing(type="int") @VintfStability
+    enum TtyMode {
+      UNSPECIFIED = (-1),
+      OFF = 0,
+      FULL = 1,
+      HCO = 2,
+      VCO = 3,
+    }
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 40a8d72..959594b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 union HapticGenerator {
   android.hardware.audio.effect.VendorExtension vendorExtension;
-  android.hardware.audio.effect.HapticGenerator.HapticScale hapticScale;
+  android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
   android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
   @VintfStability
   union Id {
diff --git a/audio/aidl/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..21ac8e2
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.Boolean;
+import android.media.audio.common.Float;
+import android.media.audio.common.Int;
+
+/**
+ * An instance of IBluetooth manages settings for the Hands-Free Profile (HFP)
+ * and the SCO Link. This interface is optional to implement and provide by the
+ * vendor. It needs to be provided only if the device actually supports BT SCO
+ * or HFP.
+ */
+@VintfStability
+interface IBluetooth {
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable ScoConfig {
+        /**
+         * Whether BT SCO is enabled. The client might need to disable it
+         * when another profile (for example, A2DP) is activated.
+         */
+        @nullable Boolean isEnabled;
+        /**
+         * Whether BT SCO Noise Reduction and Echo Cancellation are enabled.
+         */
+        @nullable Boolean isNrecEnabled;
+        @VintfStability enum Mode { UNSPECIFIED, SCO, SCO_WB, SCO_SWB }
+        /**
+         * If set, specifies the SCO mode to use:
+         *   regular, wide band (WB), or super wide band (SWB).
+         */
+        Mode mode = Mode.UNSPECIFIED;
+        /**
+         * The name of the BT SCO headset used for debugging purposes. Can be empty.
+         */
+        @nullable @utf8InCpp String debugName;
+    }
+
+    /**
+     * Set the configuration of Bluetooth SCO.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values. It is allowed to change
+     * parameters while the SCO profile is disabled (isEnabled.value == false).
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values. If the SCO profile is
+     * currently disabled (isEnabled.value == false), the parameters must
+     * reflect the last values that were in use.
+     *
+     * The client can pass an uninitialized parcelable in order to retrieve the
+     * current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If BT SCO is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    ScoConfig setScoConfig(in ScoConfig config);
+
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable HfpConfig {
+        /**
+         * Whether BT HFP is enabled.
+         */
+        @nullable Boolean isEnabled;
+        /**
+         * The sample rate of BT HFP, in Hertz. Must be a positive number.
+         */
+        @nullable Int sampleRate;
+
+        const int VOLUME_MIN = 0;
+        const int VOLUME_MAX = 1;
+        /**
+         * The output volume of BT HFP. 1.0f means unity gain, 0.0f is muted,
+         * see VOLUME_* constants;
+         */
+        @nullable Float volume;
+    }
+
+    /**
+     * Set the configuration of Bluetooth HFP.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values. It is allowed to change
+     * parameters while the HFP profile is disabled (isEnabled.value == false).
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values. If the HFP profile is
+     * currently disabled (isEnabled.value == false), the parameters must
+     * reflect the last values that were in use.
+     *
+     * The client can pass an uninitialized parcelable in order to retrieve the
+     * current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If BT HFP is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    HfpConfig setHfpConfig(in HfpConfig config);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 4779f1f..7bc1b9c 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -21,6 +21,7 @@
 import android.hardware.audio.core.AudioMode;
 import android.hardware.audio.core.AudioPatch;
 import android.hardware.audio.core.AudioRoute;
+import android.hardware.audio.core.IBluetooth;
 import android.hardware.audio.core.IStreamCallback;
 import android.hardware.audio.core.IStreamIn;
 import android.hardware.audio.core.IStreamOut;
@@ -86,6 +87,20 @@
     @nullable ITelephony getTelephony();
 
     /**
+     * Retrieve the interface to control Bluetooth SCO and HFP.
+     *
+     * If the HAL module supports either the SCO Link or Hands-Free Profile
+     * functionality (or both) for Bluetooth, it must return an instance of the
+     * IBluetooth interface. The same instance must be returned during the
+     * lifetime of the HAL module. If the HAL module does not support BT SCO and
+     * HFP, a null must be returned, without throwing any errors.
+     *
+     * @return An instance of the IBluetooth interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetooth getBluetooth();
+
+    /**
      * Set a device port of an external device into connected state.
      *
      * This method is used to inform the HAL module that an external device has
diff --git a/audio/aidl/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
index a872c7c..a817032 100644
--- a/audio/aidl/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
@@ -17,6 +17,8 @@
 package android.hardware.audio.core;
 
 import android.hardware.audio.core.AudioMode;
+import android.media.audio.common.Boolean;
+import android.media.audio.common.Float;
 
 /**
  * An instance of ITelephony manages settings which are specific to voice calls
@@ -53,4 +55,75 @@
      * @throws EX_ILLEGAL_STATE If there was an error during switching.
      */
     void switchAudioMode(AudioMode mode);
+
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable TelecomConfig {
+        const int VOICE_VOLUME_MIN = 0;
+        const int VOICE_VOLUME_MAX = 1;
+        /**
+         * Volume of a voice call. 1.0f means unity gain, 0.0f is muted,
+         * see VOLUME_* constants.
+         */
+        @nullable Float voiceVolume;
+        /**
+         * The current mode of teletypewritter (TTY).
+         */
+        @VintfStability
+        @Backing(type="int")
+        enum TtyMode {
+            /**
+             * The default uninitialized value.
+             */
+            UNSPECIFIED = -1,
+            /**
+             * TTY mode is off.
+             */
+            OFF = 0,
+            /**
+             * TTY mode is on. The speaker is off and the microphone is muted. The
+             * user will communicate with the remote party by sending and receiving
+             * text messages.
+             */
+            FULL = 1,
+            /**
+             * TTY mode is in hearing carryover mode (HCO). The microphone is muted
+             * but the speaker is on. The user will communicate with the remote
+             * party by sending text messages and hearing an audible reply.
+             */
+            HCO = 2,
+            /**
+             * TTY mode is in voice carryover mode (VCO). The speaker is off but the
+             * microphone is still on. User will communicate with the remote party
+             * by speaking and receiving text message replies.
+             */
+            VCO = 3,
+        }
+        TtyMode ttyMode = TtyMode.UNSPECIFIED;
+        /**
+         * Whether Hearing Aid Compatibility - Telecoil (HAC-T) mode is enabled.
+         */
+        @nullable Boolean isHacEnabled;
+    }
+
+    /**
+     * Set the configuration of the telephony audio.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values.
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values.The client can pass an
+     * uninitialized parcelable in order to retrieve the current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If telephony is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    TelecomConfig setTelecomConfig(in TelecomConfig config);
 }
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 944155f..3063ee3 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -90,6 +90,6 @@
         float maxAmplitude;
     }
 
-    HapticScale hapticScale;
+    HapticScale[] hapticScales;
     VibratorInformation vibratorInfo;
 }
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 8cd56c0..6f23636 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -62,6 +62,7 @@
     export_include_dirs: ["include"],
     srcs: [
         "AudioPolicyConfigXmlConverter.cpp",
+        "Bluetooth.cpp",
         "Config.cpp",
         "Configuration.cpp",
         "EngineConfigXmlConverter.cpp",
diff --git a/audio/aidl/default/Bluetooth.cpp b/audio/aidl/default/Bluetooth.cpp
new file mode 100644
index 0000000..38e0c21
--- /dev/null
+++ b/audio/aidl/default/Bluetooth.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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_Bluetooth"
+#include <android-base/logging.h>
+
+#include "core-impl/Bluetooth.h"
+
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
+
+namespace aidl::android::hardware::audio::core {
+
+Bluetooth::Bluetooth() {
+    mScoConfig.isEnabled = Boolean{false};
+    mScoConfig.isNrecEnabled = Boolean{false};
+    mScoConfig.mode = ScoConfig::Mode::SCO;
+    mHfpConfig.isEnabled = Boolean{false};
+    mHfpConfig.sampleRate = Int{8000};
+    mHfpConfig.volume = Float{HfpConfig::VOLUME_MAX};
+}
+
+ndk::ScopedAStatus Bluetooth::setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) {
+    if (in_config.isEnabled.has_value()) {
+        mScoConfig.isEnabled = in_config.isEnabled;
+    }
+    if (in_config.isNrecEnabled.has_value()) {
+        mScoConfig.isNrecEnabled = in_config.isNrecEnabled;
+    }
+    if (in_config.mode != ScoConfig::Mode::UNSPECIFIED) {
+        mScoConfig.mode = in_config.mode;
+    }
+    if (in_config.debugName.has_value()) {
+        mScoConfig.debugName = in_config.debugName;
+    }
+    *_aidl_return = mScoConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Bluetooth::setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) {
+    if (in_config.sampleRate.has_value() && in_config.sampleRate.value().value <= 0) {
+        LOG(ERROR) << __func__ << ": invalid sample rate: " << in_config.sampleRate.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_config.volume.has_value() && (in_config.volume.value().value < HfpConfig::VOLUME_MIN ||
+                                         in_config.volume.value().value > HfpConfig::VOLUME_MAX)) {
+        LOG(ERROR) << __func__ << ": invalid volume: " << in_config.volume.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    if (in_config.isEnabled.has_value()) {
+        mHfpConfig.isEnabled = in_config.isEnabled;
+    }
+    if (in_config.sampleRate.has_value()) {
+        mHfpConfig.sampleRate = in_config.sampleRate;
+    }
+    if (in_config.volume.has_value()) {
+        mHfpConfig.volume = in_config.volume;
+    }
+    *_aidl_return = mHfpConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index b58c562..e8b5bfc 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -25,6 +25,7 @@
 #include <aidl/android/media/audio/common/AudioInputFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 
+#include "core-impl/Bluetooth.h"
 #include "core-impl/Module.h"
 #include "core-impl/SoundDose.h"
 #include "core-impl/Telephony.h"
@@ -326,6 +327,18 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
+    if (mBluetooth == nullptr) {
+        mBluetooth = ndk::SharedRefBase::make<Bluetooth>();
+        mBluetoothBinder = mBluetooth->asBinder();
+        AIBinder_setMinSchedulerPolicy(mBluetoothBinder.get(), SCHED_NORMAL,
+                                       ANDROID_PRIORITY_AUDIO);
+    }
+    *_aidl_return = mBluetooth;
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
                                                  AudioPort* _aidl_return) {
     const int32_t templateId = in_templateIdAndAdditionalData.id;
diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp
index 1854b35..d873178 100644
--- a/audio/aidl/default/Telephony.cpp
+++ b/audio/aidl/default/Telephony.cpp
@@ -20,8 +20,17 @@
 
 #include "core-impl/Telephony.h"
 
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+
 namespace aidl::android::hardware::audio::core {
 
+Telephony::Telephony() {
+    mTelecomConfig.voiceVolume = Float{TelecomConfig::VOICE_VOLUME_MAX};
+    mTelecomConfig.ttyMode = TelecomConfig::TtyMode::OFF;
+    mTelecomConfig.isHacEnabled = Boolean{false};
+}
+
 ndk::ScopedAStatus Telephony::getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) {
     *_aidl_return = mSupportedAudioModes;
     LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
@@ -38,4 +47,28 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+ndk::ScopedAStatus Telephony::setTelecomConfig(const TelecomConfig& in_config,
+                                               TelecomConfig* _aidl_return) {
+    if (in_config.voiceVolume.has_value() &&
+        (in_config.voiceVolume.value().value < TelecomConfig::VOICE_VOLUME_MIN ||
+         in_config.voiceVolume.value().value > TelecomConfig::VOICE_VOLUME_MAX)) {
+        LOG(ERROR) << __func__
+                   << ": voice volume value is invalid: " << in_config.voiceVolume.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_config.voiceVolume.has_value()) {
+        mTelecomConfig.voiceVolume = in_config.voiceVolume;
+    }
+    if (in_config.ttyMode != TelecomConfig::TtyMode::UNSPECIFIED) {
+        mTelecomConfig.ttyMode = in_config.ttyMode;
+    }
+    if (in_config.isHacEnabled.has_value()) {
+        mTelecomConfig.isHacEnabled = in_config.isHacEnabled;
+    }
+    *_aidl_return = mTelecomConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index f6211c4..3c3b66f 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -90,8 +90,8 @@
     auto tag = hgParam.getTag();
 
     switch (tag) {
-        case HapticGenerator::hapticScale: {
-            RETURN_IF(mContext->setHgHapticScale(hgParam.get<HapticGenerator::hapticScale>()) !=
+        case HapticGenerator::hapticScales: {
+            RETURN_IF(mContext->setHgHapticScales(hgParam.get<HapticGenerator::hapticScales>()) !=
                               RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "HapticScaleNotSupported");
             return ndk::ScopedAStatus::ok();
@@ -133,8 +133,8 @@
 
     HapticGenerator hgParam;
     switch (tag) {
-        case HapticGenerator::hapticScale: {
-            hgParam.set<HapticGenerator::hapticScale>(mContext->getHgHapticScale());
+        case HapticGenerator::hapticScales: {
+            hgParam.set<HapticGenerator::hapticScales>(mContext->getHgHapticScales());
             break;
         }
         case HapticGenerator::vibratorInfo: {
@@ -183,4 +183,20 @@
     return {STATUS_OK, samples, samples};
 }
 
+RetCode HapticGeneratorSwContext::setHgHapticScales(
+        const std::vector<HapticGenerator::HapticScale>& hapticScales) {
+    // Assume any audio track ID is valid
+    for (auto& it : hapticScales) {
+        mHapticScales[it.id] = it;
+    }
+    return RetCode::SUCCESS;
+}
+
+std::vector<HapticGenerator::HapticScale> HapticGeneratorSwContext::getHgHapticScales() const {
+    std::vector<HapticGenerator::HapticScale> result;
+    std::transform(mHapticScales.begin(), mHapticScales.end(), std::back_inserter(result),
+                   [](auto& scaleIt) { return scaleIt.second; });
+    return result;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index d9ec744..7159501 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -33,12 +33,8 @@
         LOG(DEBUG) << __func__;
     }
 
-    RetCode setHgHapticScale(const HapticGenerator::HapticScale& hapticScale) {
-        // All int values are valid for ID
-        mHapticScale = hapticScale;
-        return RetCode::SUCCESS;
-    }
-    HapticGenerator::HapticScale getHgHapticScale() const { return mHapticScale; }
+    RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales);
+    std::vector<HapticGenerator::HapticScale> getHgHapticScales() const;
 
     RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo) {
         // All float values are valid for resonantFrequencyHz, qFactor, maxAmplitude
@@ -54,7 +50,7 @@
     static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f;
     static constexpr float DEFAULT_Q_FACTOR = 1.0f;
     static constexpr float DEFAULT_MAX_AMPLITUDE = 0.0f;
-    HapticGenerator::HapticScale mHapticScale = {0, HapticGenerator::VibratorScale::MUTE};
+    std::map<int /* trackID */, HapticGenerator::HapticScale> mHapticScales;
     HapticGenerator::VibratorInformation mVibratorInformation = {
             DEFAULT_RESONANT_FREQUENCY, DEFAULT_Q_FACTOR, DEFAULT_MAX_AMPLITUDE};
 };
diff --git a/audio/aidl/default/include/core-impl/Bluetooth.h b/audio/aidl/default/include/core-impl/Bluetooth.h
new file mode 100644
index 0000000..f2e762d
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Bluetooth.h
@@ -0,0 +1,35 @@
+/*
+ * 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/BnBluetooth.h>
+
+namespace aidl::android::hardware::audio::core {
+
+class Bluetooth : public BnBluetooth {
+  public:
+    Bluetooth();
+
+  private:
+    ndk::ScopedAStatus setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) override;
+    ndk::ScopedAStatus setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) override;
+
+    ScoConfig mScoConfig;
+    HfpConfig mHfpConfig;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index faca61e..e9f43d8 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -39,6 +39,7 @@
     ndk::ScopedAStatus setModuleDebug(
             const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
     ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
     ndk::ScopedAStatus connectExternalDevice(
             const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
             ::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
@@ -127,10 +128,12 @@
     const Type mType;
     std::unique_ptr<internal::Configuration> mConfig;
     ModuleDebug mDebug;
-    // Since it is required to return the same instance of the ITelephony, even
-    // if the client has released it on its side, we need to hold it via a strong pointer.
+    // For the interfaces requiring to return the same instance, we need to hold them
+    // via a strong pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
     std::shared_ptr<ITelephony> mTelephony;
     ndk::SpAIBinder mTelephonyBinder;
+    std::shared_ptr<IBluetooth> mBluetooth;
+    ndk::SpAIBinder mBluetoothBinder;
     // ids of ports created at runtime via 'connectExternalDevice'.
     std::set<int32_t> mConnectedDevicePorts;
     Streams mStreams;
diff --git a/audio/aidl/default/include/core-impl/Telephony.h b/audio/aidl/default/include/core-impl/Telephony.h
index 597f3d6..0936172 100644
--- a/audio/aidl/default/include/core-impl/Telephony.h
+++ b/audio/aidl/default/include/core-impl/Telephony.h
@@ -23,12 +23,18 @@
 namespace aidl::android::hardware::audio::core {
 
 class Telephony : public BnTelephony {
+  public:
+    Telephony();
+
   private:
     ndk::ScopedAStatus getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) override;
     ndk::ScopedAStatus switchAudioMode(AudioMode in_mode) override;
+    ndk::ScopedAStatus setTelecomConfig(const TelecomConfig& in_config,
+                                        TelecomConfig* _aidl_return) override;
 
     const std::vector<AudioMode> mSupportedAudioModes = {::ndk::enum_range<AudioMode>().begin(),
                                                          ::ndk::enum_range<AudioMode>().end()};
+    TelecomConfig mTelecomConfig;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 50a93ce..8da475e 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -56,6 +56,7 @@
 using aidl::android::hardware::audio::core::AudioMode;
 using aidl::android::hardware::audio::core::AudioPatch;
 using aidl::android::hardware::audio::core::AudioRoute;
+using aidl::android::hardware::audio::core::IBluetooth;
 using aidl::android::hardware::audio::core::IModule;
 using aidl::android::hardware::audio::core::IStreamCommon;
 using aidl::android::hardware::audio::core::IStreamIn;
@@ -84,6 +85,8 @@
 using aidl::android::media::audio::common::AudioPortExt;
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
 using aidl::android::media::audio::common::Void;
 using android::hardware::audio::common::getChannelCount;
 using android::hardware::audio::common::isBitPositionFlagSet;
@@ -1775,6 +1778,89 @@
     }
 }
 
+class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetooth(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetooth> bluetooth;
+};
+
+TEST_P(AudioCoreBluetooth, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    std::shared_ptr<IBluetooth> bluetooth2;
+    EXPECT_IS_OK(module->getBluetooth(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetooth must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetooth, ScoConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::ScoConfig scoConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setScoConfig({}, &scoConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT SCO is not supported";
+    }
+    EXPECT_TRUE(scoConfig.isEnabled.has_value());
+    EXPECT_TRUE(scoConfig.isNrecEnabled.has_value());
+    EXPECT_NE(IBluetooth::ScoConfig::Mode::UNSPECIFIED, scoConfig.mode);
+    IBluetooth::ScoConfig scoConfig2;
+    ASSERT_IS_OK(bluetooth->setScoConfig(scoConfig, &scoConfig2));
+    EXPECT_EQ(scoConfig, scoConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::HfpConfig hfpConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT HFP is not supported";
+    }
+    EXPECT_TRUE(hfpConfig.isEnabled.has_value());
+    EXPECT_TRUE(hfpConfig.sampleRate.has_value());
+    EXPECT_TRUE(hfpConfig.volume.has_value());
+    IBluetooth::HfpConfig hfpConfig2;
+    ASSERT_IS_OK(bluetooth->setHfpConfig(hfpConfig, &hfpConfig2));
+    EXPECT_EQ(hfpConfig, hfpConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfigInvalid) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::HfpConfig hfpConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT HFP is not supported";
+    }
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.sampleRate = Int{-1}}, &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, bluetooth->setHfpConfig({.sampleRate = Int{0}}, &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MIN - 1}},
+                                          &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MAX + 1}},
+                                          &hfpConfig));
+}
+
 class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
   public:
     void SetUp() override {
@@ -1787,6 +1873,17 @@
     std::shared_ptr<ITelephony> telephony;
 };
 
+TEST_P(AudioCoreTelephony, SameInstance) {
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    std::shared_ptr<ITelephony> telephony2;
+    EXPECT_IS_OK(module->getTelephony(&telephony2));
+    ASSERT_NE(nullptr, telephony2.get());
+    EXPECT_EQ(telephony->asBinder(), telephony2->asBinder())
+            << "getTelephony must return the same interface instance across invocations";
+}
+
 TEST_P(AudioCoreTelephony, GetSupportedAudioModes) {
     if (telephony == nullptr) {
         GTEST_SKIP() << "Telephony is not supported";
@@ -1828,6 +1925,46 @@
     }
 }
 
+TEST_P(AudioCoreTelephony, TelecomConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    ndk::ScopedAStatus status;
+    ITelephony::TelecomConfig telecomConfig;
+    ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Telecom is not supported";
+    }
+    EXPECT_TRUE(telecomConfig.voiceVolume.has_value());
+    EXPECT_NE(ITelephony::TelecomConfig::TtyMode::UNSPECIFIED, telecomConfig.ttyMode);
+    EXPECT_TRUE(telecomConfig.isHacEnabled.has_value());
+    ITelephony::TelecomConfig telecomConfig2;
+    ASSERT_IS_OK(telephony->setTelecomConfig(telecomConfig, &telecomConfig2));
+    EXPECT_EQ(telecomConfig, telecomConfig2);
+}
+
+TEST_P(AudioCoreTelephony, TelecomConfigInvalid) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    ndk::ScopedAStatus status;
+    ITelephony::TelecomConfig telecomConfig;
+    ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Telecom is not supported";
+    }
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  telephony->setTelecomConfig(
+                          {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MIN - 1}},
+                          &telecomConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  telephony->setTelecomConfig(
+                          {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MAX + 1}},
+                          &telecomConfig));
+}
+
 using CommandSequence = std::vector<StreamDescriptor::Command>;
 class StreamLogicDriverInvalidCommand : public StreamLogicDriver {
   public:
@@ -2998,6 +3135,17 @@
     return ndk::ScopedAStatus::ok();
 }
 
+TEST_P(AudioCoreSoundDose, SameInstance) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+    std::shared_ptr<ISoundDose> soundDose2;
+    EXPECT_IS_OK(module->getSoundDose(&soundDose2));
+    ASSERT_NE(nullptr, soundDose2.get());
+    EXPECT_EQ(soundDose->asBinder(), soundDose2->asBinder())
+            << "getSoundDose must return the same interface instance across invocations";
+}
+
 TEST_P(AudioCoreSoundDose, GetSetOutputRs2) {
     if (soundDose == nullptr) {
         GTEST_SKIP() << "SoundDose is not supported";
@@ -3044,6 +3192,10 @@
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothTest, AudioCoreBluetooth,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetooth);
 INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index d1f3b97..b8ea9c1 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -19,7 +19,9 @@
 #include <Utils.h>
 #include <aidl/Vintf.h>
 #include <android/binder_enums.h>
-#include <unordered_set>
+#include <map>
+#include <utility>
+#include <vector>
 
 #include "EffectHelper.h"
 
@@ -87,12 +89,11 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
     }
 
@@ -101,15 +102,6 @@
         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
     }
 
-    Parameter::Specific getDefaultParamSpecific() {
-        HapticGenerator::HapticScale hapticScale = {.id = 0,
-                                                    .scale = HapticGenerator::VibratorScale::MUTE};
-        HapticGenerator hg = HapticGenerator::make<HapticGenerator::hapticScale>(hapticScale);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::hapticGenerator>(hg);
-        return specific;
-    }
-
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
@@ -122,13 +114,13 @@
 
     void SetAndGetHapticGeneratorParameters() {
         for (auto& it : mTags) {
-            auto& tag = it.first;
-            auto& hg = it.second;
+            auto& tag = std::get<ParamTestEnum::PARAM_TEST_TAG>(it);
+            auto& setHg = std::get<ParamTestEnum::PARAM_TEST_TARGET>(it);
 
             // set parameter
             Parameter expectParam;
             Parameter::Specific specific;
-            specific.set<Parameter::Specific::hapticGenerator>(hg);
+            specific.set<Parameter::Specific::hapticGenerator>(setHg);
             expectParam.set<Parameter::specific>(specific);
             EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
 
@@ -139,15 +131,16 @@
             hgId.set<HapticGenerator::Id::commonTag>(tag);
             id.set<Parameter::Id::hapticGeneratorTag>(hgId);
             EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-            EXPECT_EQ(expectParam, getParam);
+            EXPECT_EQ(expectParam, getParam) << expectParam.toString() << "\n"
+                                             << getParam.toString();
         }
     }
 
     void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) {
-        HapticGenerator hg;
-        HapticGenerator::HapticScale hapticScale = {.id = id, .scale = scale};
-        hg.set<HapticGenerator::hapticScale>(hapticScale);
-        mTags.push_back({HapticGenerator::hapticScale, hg});
+        HapticGenerator setHg;
+        std::vector<HapticGenerator::HapticScale> hapticScales = {{.id = id, .scale = scale}};
+        setHg.set<HapticGenerator::hapticScales>(hapticScales);
+        mTags.push_back({HapticGenerator::hapticScales, setHg});
     }
 
     void addVibratorInformationParam(float resonantFrequencyHz, float qFactor, float maxAmplitude) {
@@ -161,7 +154,8 @@
     }
 
   private:
-    std::vector<std::pair<HapticGenerator::Tag, HapticGenerator>> mTags;
+    enum ParamTestEnum { PARAM_TEST_TAG, PARAM_TEST_TARGET };
+    std::vector<std::tuple<HapticGenerator::Tag, HapticGenerator>> mTags;
 
     void CleanUp() { mTags.clear(); }
 };
@@ -171,6 +165,12 @@
     SetAndGetHapticGeneratorParameters();
 }
 
+TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+    SetAndGetHapticGeneratorParameters();
+}
+
 TEST_P(HapticGeneratorParamTest, SetAndGetVibratorInformation) {
     EXPECT_NO_FATAL_FAILURE(addVibratorInformationParam(mParamResonantFrequency, mParamQFactor,
                                                         mParamMaxAmplitude));
@@ -212,7 +212,7 @@
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kHapticGeneratorTypeUUID)),
                            testing::Values(MIN_ID - 1),
-                           testing::Values(HapticGenerator::VibratorScale::MUTE),
+                           testing::Values(HapticGenerator::VibratorScale::NONE),
                            testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
                            testing::Values(MIN_FLOAT)),
         [](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
@@ -236,9 +236,202 @@
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
         });
-
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorParamTest);
 
+// Test HapticScale[] hapticScales parameter
+using HapticGeneratorScalesTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
+class HapticGeneratorScalesTest : public ::testing::TestWithParam<HapticGeneratorScalesTestParam>,
+                                  public EffectHelper {
+  public:
+    HapticGeneratorScalesTest() {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        CleanUp();
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+
+    void addHapticScaleParam(std::vector<HapticGenerator::HapticScale> scales) {
+        mHapticScales.push_back(HapticGenerator::make<HapticGenerator::hapticScales>(scales));
+        for (const auto& scale : scales) {
+            expectMap.insert_or_assign(scale.id, scale.scale);
+        }
+    }
+
+    void SetHapticScaleParameters() {
+        // std::unordered_set<HapticGenerator::HapticScale> target;
+        for (auto& it : mHapticScales) {
+            Parameter::Specific specific =
+                    Parameter::Specific::make<Parameter::Specific::hapticGenerator>(it);
+            Parameter param = Parameter::make<Parameter::specific>(specific);
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
+        }
+    }
+
+    void checkHapticScaleParameter() {
+        // get parameter
+        Parameter targetParam;
+        HapticGenerator::Id hgId = HapticGenerator::Id::make<HapticGenerator::Id::commonTag>(
+                HapticGenerator::hapticScales);
+        Parameter::Id id = Parameter::Id::make<Parameter::Id::hapticGeneratorTag>(hgId);
+        EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &targetParam));
+        ASSERT_EQ(Parameter::specific, targetParam.getTag());
+        Parameter::Specific specific = targetParam.get<Parameter::specific>();
+        ASSERT_EQ(Parameter::Specific::hapticGenerator, specific.getTag());
+        HapticGenerator hg = specific.get<Parameter::Specific::hapticGenerator>();
+        ASSERT_EQ(HapticGenerator::hapticScales, hg.getTag());
+        std::vector<HapticGenerator::HapticScale> scales = hg.get<HapticGenerator::hapticScales>();
+        ASSERT_EQ(scales.size(), expectMap.size());
+        for (const auto& scale : scales) {
+            auto itor = expectMap.find(scale.id);
+            ASSERT_NE(expectMap.end(), itor);
+            ASSERT_EQ(scale.scale, itor->second);
+            expectMap.erase(scale.id);
+        }
+        ASSERT_EQ(0ul, expectMap.size());
+    }
+
+    const static HapticGenerator::HapticScale kHapticScaleWithMinId;
+    const static HapticGenerator::HapticScale kHapticScaleWithMinIdNew;
+    const static HapticGenerator::HapticScale kHapticScale;
+    const static HapticGenerator::HapticScale kHapticScaleNew;
+    const static HapticGenerator::HapticScale kHapticScaleWithMaxId;
+    const static HapticGenerator::HapticScale kHapticScaleWithMaxIdNew;
+
+    std::vector<HapticGenerator> mHapticScales;
+
+    void CleanUp() {
+        mHapticScales.clear();
+        expectMap.clear();
+    }
+
+  private:
+    std::map<int /* trackID */, HapticGenerator::VibratorScale> expectMap;
+};
+
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinId = {
+        .id = MIN_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinIdNew = {
+        .id = MIN_ID, .scale = HapticGenerator::VibratorScale::VERY_LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScale = {
+        .id = 1, .scale = HapticGenerator::VibratorScale::LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleNew = {
+        .id = 1, .scale = HapticGenerator::VibratorScale::NONE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxId = {
+        .id = MAX_ID, .scale = HapticGenerator::VibratorScale::VERY_HIGH};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxIdNew = {
+        .id = MAX_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateOne) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateVector) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+            {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateMultipleVector) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+            {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetOneAndAddMoreVector) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleAndAddOneVector) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleVectorRepeat) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        HapticGeneratorScalesTest, HapticGeneratorScalesTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                IFactory::descriptor, kHapticGeneratorTypeUUID))),
+        [](const testing::TestParamInfo<HapticGeneratorScalesTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString();
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScalesTest);
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
index e82f6fa..3452ae9 100644
--- a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -1,5 +1,6 @@
 <manifest version="2.0" type="device">
     <hal format="aidl">
+        <version>2</version>
         <name>android.hardware.automotive.audiocontrol</name>
         <fqname>IAudioControl/default</fqname>
     </hal>
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 9e4f252..83b0d94 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2117,6 +2117,12 @@
         | VehicleArea:SEAT),
 
     /**
+     * DO NOT USE
+     *
+     * This property is defined as type VehicleArea:GLOBAL, which means all seats use the same
+     * value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by being defined as
+     * type VehicleArea:SEAT.
+     *
      * Headrest height position
      *
      * Sets the headrest height.
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..3be8d12
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvStoppingMode {
+  OTHER = 0,
+  CREEP = 1,
+  ROLL = 2,
+  HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index c3b3e00..914787e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -80,6 +80,7 @@
   IGNITION_STATE = 289408009,
   ABS_ACTIVE = 287310858,
   TRACTION_CONTROL_ACTIVE = 287310859,
+  EV_STOPPING_MODE = 289408013,
   HVAC_FAN_SPEED = 356517120,
   HVAC_FAN_DIRECTION = 356517121,
   HVAC_TEMPERATURE_CURRENT = 358614274,
@@ -155,11 +156,14 @@
   SEAT_LUMBAR_SIDE_SUPPORT_POS = 356518803,
   SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 356518804,
   SEAT_HEADREST_HEIGHT_POS = 289409941,
+  SEAT_HEADREST_HEIGHT_POS_V2 = 356518820,
   SEAT_HEADREST_HEIGHT_MOVE = 356518806,
   SEAT_HEADREST_ANGLE_POS = 356518807,
   SEAT_HEADREST_ANGLE_MOVE = 356518808,
   SEAT_HEADREST_FORE_AFT_POS = 356518809,
   SEAT_HEADREST_FORE_AFT_MOVE = 356518810,
+  SEAT_FOOTWELL_LIGHTS_STATE = 356518811,
+  SEAT_FOOTWELL_LIGHTS_SWITCH = 356518812,
   SEAT_EASY_ACCESS_ENABLED = 354421661,
   SEAT_AIRBAG_ENABLED = 354421662,
   SEAT_CUSHION_SIDE_SUPPORT_POS = 356518815,
@@ -195,6 +199,8 @@
   CABIN_LIGHTS_SWITCH = 289410818,
   READING_LIGHTS_STATE = 356519683,
   READING_LIGHTS_SWITCH = 356519684,
+  STEERING_WHEEL_LIGHTS_STATE = 289410828,
+  STEERING_WHEEL_LIGHTS_SWITCH = 289410829,
   SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 287313669,
   DISABLED_OPTIONAL_FEATURES = 286265094,
   INITIAL_USER_INFO = 299896583,
@@ -231,4 +237,14 @@
   GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 289410887,
   SUPPORTED_PROPERTY_IDS = 289476424,
   SHUTDOWN_REQUEST = 289410889,
+  AUTOMATIC_EMERGENCY_BRAKING_ENABLED = 287313920,
+  FORWARD_COLLISION_WARNING_ENABLED = 287313922,
+  BLIND_SPOT_WARNING_ENABLED = 287313924,
+  LANE_DEPARTURE_WARNING_ENABLED = 287313926,
+  LANE_KEEP_ASSIST_ENABLED = 287313928,
+  LANE_CENTERING_ASSIST_ENABLED = 287313930,
+  EMERGENCY_LANE_KEEP_ASSIST_ENABLED = 287313933,
+  ADAPTIVE_CRUISE_CONTROL_ENABLED = 287313935,
+  HANDS_ON_DETECTION_ENABLED = 287313941,
+  DRIVER_ATTENTION_MONITORING_ENABLED = 287313944,
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..8c5ac46
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EV_STOPPING_MODE to enumerate the current state of the stopping mode.
+ *
+ * This enum may be extended to include more states in the future.
+ */
+@VintfStability
+@Backing(type="int")
+enum EvStoppingMode {
+    /**
+     * Other EV stopping mode. Ideally, this should never be used.
+     */
+    OTHER = 0,
+    /**
+     * Vehicle slowly moves forward when the brake pedal is released.
+     */
+    CREEP = 1,
+    /**
+     * Vehicle rolls freely when the brake pedal is released (similar to neutral gear).
+     */
+    ROLL = 2,
+    /**
+     * Vehicle stops and holds its position when the brake pedal is released.
+     */
+    HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 4d0b77b..e776154 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -603,6 +603,20 @@
     TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
     /**
+     * Represents property for the current stopping mode of the vehicle.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of EvStoppingMode are supported.
+     *
+     * The EvStoppingMode enum may be extended to include more states in the future.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum EvStoppingMode
+     */
+    EV_STOPPING_MODE =
+            0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
      * HVAC Properties
      *
      * Additional rules for mapping a zoned HVAC property (except
@@ -1760,7 +1774,11 @@
     SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
     /**
-     * Headrest height position
+     * (Deprecated) Headrest height position
+     *
+     * This property is deprecated because it is defined as type VehicleArea:GLOBAL, which means all
+     * seats use the same value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by
+     * being defined as type VehicleArea:SEAT.
      *
      * Sets the headrest height.
      * Max value indicates tallest setting.
@@ -1771,6 +1789,25 @@
      */
     SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Headrest height position
+     *
+     * Sets the headrest height for supported seats. VehiclePropConfig.areaConfigs specifies which
+     * seats are supported.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported. The maxInt32Value indicates the tallest
+     * setting and the minInt32Value indicates the shortest setting.
+     *
+     * This value is not in any particular unit but in a specified range of steps.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_POS_V2 =
+            0x0BA4 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+
     /**
      * Headrest height move
      *
@@ -1824,6 +1861,48 @@
     SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
     /**
+     * Represents property for the seat footwell lights state.
+     *
+     * SEAT_FOOTWELL_LIGHTS_STATE reflects the current state of the lights at any point in time.
+     * This is different from the function of SEAT_FOOTWELL_LIGHTS_SWITCH which represents the
+     * position of the switch controlling the lights. Therefore, SEAT_FOOTWELL_LIGHTS_STATE may not
+     * match the value of SEAT_FOOTWELL_LIGHTS_SWITCH (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC
+     * and SEAT_FOOTWELL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_STATE's value may be
+     * different from that of CABIN_LIGHTS_STATE.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    SEAT_FOOTWELL_LIGHTS_STATE =
+            0x0B9B + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for the seat footwell lights switch.
+     *
+     * SEAT_FOOTWELL_LIGHTS_SWITCH represents the position of the switch controlling the lights.
+     * This is different from the function of SEAT_FOOTWELL_LIGHTS_STATE which reflects the current
+     * state of the lights at any point in time. Therefore, SEAT_FOOTWELL_LIGHTS_SWITCH may not
+     * match the value of SEAT_FOOTWELL_LIGHTS_STATE (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC and
+     * SEAT_FOOTWELL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_SWITCH's value may be
+     * different from that of CABIN_LIGHTS_SWITCH.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightSwitch are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    SEAT_FOOTWELL_LIGHTS_SWITCH =
+            0x0B9C + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
      * Represents property for Seat easy access feature.
      *
      * If true, the seat will automatically adjust to make it easier for the occupant to enter and
@@ -2414,6 +2493,48 @@
     READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
     /**
+     * Steering wheel lights state
+     *
+     * Represents the current state of the steering wheel lights. This is different from
+     * STEERING_WHEEL_LIGHTS_SWITCH which represents the position of the switch controlling
+     * the lights. Therefore, STEERING_WHEEL_LIGHTS_STATE may not match the value of
+     * STEERING_WHEEL_LIGHTS_SWITCH (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+     * STEERING_WHEEL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if STEERING_WHEEL_LIGHTS_STATE's value may be
+     * different from that of CABIN_LIGHTS_STATE.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    STEERING_WHEEL_LIGHTS_STATE =
+            0x0F0C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel lights switch
+     *
+     * Represents the position of the switch controlling the steering wheel lights. This is
+     * different from STEERING_WHEEL_LIGHTS_STATE which represents the current state of the steering
+     * wheel lights. Therefore, STEERING_WHEEL_LIGHTS_SWITCH may not match the value of
+     * STEERING_WHEEL_LIGHTS_STATE (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+     * STEERING_WHEEL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if STEERING_WHEEL_LIGHTS_SWITCH's value may be
+     * different from that of CABIN_LIGHTS_SWITCH.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightSwitch are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    STEERING_WHEEL_LIGHTS_SWITCH =
+            0x0F0D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
      * Support customize permissions for vendor properties
      *
      * Implement this property if vehicle hal support customize vendor permissions feature.
@@ -3296,4 +3417,183 @@
      */
     SHUTDOWN_REQUEST =
             0x0F49 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /***************************************************************************
+     * Start of ADAS Properties
+     * Allocate IDs in range of 0x1000 (inclusive) to 0x1100 (exclusive) for ADAS properties
+     **************************************************************************/
+
+    /**
+     * Enable or disable automatic emergency braking (AEB).
+     *
+     * Set true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring to avoid potential collisions.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
+            0x1000 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable forward collision warning (FCW).
+     *
+     * Set true to enable FCW and false to disable FCW. When FCW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring for potential collisions.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    FORWARD_COLLISION_WARNING_ENABLED =
+            0x1002 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable and disable blind spot warning (BSW).
+     *
+     * Set true to enable BSW and false to disable BSW. When BSW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring for objects in the vehicle’s blind spots.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    BLIND_SPOT_WARNING_ENABLED =
+            0x1004 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable lane departure warning (LDW).
+     *
+     * Set true to enable LDW and false to disable LDW. When LDW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring if the vehicle is approaching or crossing lane
+     * lines, in which case a warning will be given.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_DEPARTURE_WARNING_ENABLED =
+            0x1006 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable Lane Keep Assist (LKA).
+     *
+     * Set true to enable LKA and false to disable LKA. When LKA is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring if the driver unintentionally drifts toward or
+     * over the lane marking. If an unintentional lane departure is detected, the system applies
+     * steering control to return the vehicle into the current lane.
+     *
+     * This is different from Lane Centering Assist (LCA) which, when activated, applies continuous
+     * steering control to keep the vehicle centered in the current lane.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_KEEP_ASSIST_ENABLED =
+            0x1008 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable lane centering assist (LCA).
+     *
+     * Set true to enable LCA and false to disable LCA. When LCA is enabled, the ADAS system in the
+     * vehicle should be turned on and waiting for an activation signal from the driver. Once the
+     * feature is activated, the ADAS system should be steering the vehicle to keep it centered in
+     * its current lane.
+     *
+     * This is different from Lane Keep Assist (LKA) which monitors if the driver unintentionally
+     * drifts toward or over the lane marking. If an unintentional lane departure is detected, the
+     * system applies steering control to return the vehicle into the current lane.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_CENTERING_ASSIST_ENABLED =
+            0x100A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /*
+     * Enable or disable emergency lane keep assist (ELKA).
+     *
+     * Set true to enable ELKA and false to disable ELKA. When ELKA is enabled, the ADAS system in
+     * the vehicle should be on and monitoring for unsafe lane changes by the driver. When an unsafe
+     * maneuver is detected, ELKA alerts the driver and applies steering corrections to keep the
+     * vehicle in its original lane.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EMERGENCY_LANE_KEEP_ASSIST_ENABLED =
+            0x100D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable adaptive cruise control (ACC).
+     *
+     * Set true to enable ACC and false to disable ACC. When ACC is enabled, the ADAS system in the
+     * vehicle should be turned on and waiting for an activation signal from the driver. Once the
+     * feature is activated, the ADAS system in the car should be accelerating and braking in a way
+     * that allows the vehicle to maintain a set speed and to maintain a set distance gap from a
+     * leading vehicle.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    ADAPTIVE_CRUISE_CONTROL_ENABLED =
+            0x100F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable hands on detection (HOD).
+     *
+     * Set true to enable HOD and false to disable HOD. When HOD is enabled, a system inside the
+     * vehicle should be monitoring the presence of the driver's hands on the steering wheel and
+     * send a warning if it detects that the driver's hands are no longer on the steering wheel.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HANDS_ON_DETECTION_ENABLED =
+            0x1015 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Enable or disable driver attention monitoring.
+     *
+     * Set true to enable driver attention monitoring and false to disable driver attention
+     * monitoring. When driver attention monitoring is enabled, a system inside the vehicle should
+     * be monitoring the attention level of the driver and should send a warning if it detects that
+     * the driver is distracted.
+     *
+     * This property is defined as read_write, but OEMs have the option to implement it as read
+     * only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DRIVER_ATTENTION_MONITORING_ENABLED =
+            0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /***************************************************************************
+     * End of ADAS Properties
+     **************************************************************************/
 }
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index 75b371f..8b77040 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -80,6 +80,7 @@
         {VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
         {VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
         {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
@@ -155,11 +156,14 @@
         {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
@@ -195,6 +199,8 @@
         {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyAccess::READ},
         {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess::READ},
         {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess::READ},
         {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyAccess::READ_WRITE},
@@ -231,6 +237,16 @@
         {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess::READ},
         {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess::READ},
         {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DRIVER_ATTENTION_MONITORING_ENABLED, VehiclePropertyAccess::READ_WRITE},
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index 6e797b9..d7e87e2 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -80,6 +80,7 @@
         {VehicleProperty::IGNITION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -155,11 +156,14 @@
         {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
@@ -195,6 +199,8 @@
         {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
@@ -231,6 +237,16 @@
         {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_ATTENTION_MONITORING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index 455d3d4..14600f0 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -72,6 +72,7 @@
         Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
@@ -147,11 +148,14 @@
         Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
@@ -187,6 +191,8 @@
         Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyAccess.READ_WRITE),
@@ -222,7 +228,17 @@
         Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess.READ),
-        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE)
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DRIVER_ATTENTION_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE)
     );
 
 }
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index aaa344f..864f392 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -72,6 +72,7 @@
         Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -147,11 +148,14 @@
         Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
@@ -187,6 +191,8 @@
         Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
@@ -222,7 +228,17 @@
         Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode.STATIC),
-        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE)
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_ATTENTION_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE)
     );
 
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 20048a2..5521ed1 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -89,6 +89,7 @@
         {"SEAT_2_LEFT", SEAT_2_LEFT},
         {"SEAT_2_RIGHT", SEAT_2_RIGHT},
         {"SEAT_2_CENTER", SEAT_2_CENTER},
+        {"SEAT_2_LEFT_2_RIGHT_2_CENTER", SEAT_2_LEFT | SEAT_2_RIGHT | SEAT_2_CENTER},
         {"WHEEL_REAR_RIGHT", WHEEL_REAR_RIGHT},
         {"WHEEL_REAR_LEFT", WHEEL_REAR_LEFT},
         {"WHEEL_FRONT_RIGHT", WHEEL_FRONT_RIGHT},
@@ -107,7 +108,11 @@
         {"LIGHT_STATE_ON", LIGHT_STATE_ON},
         {"LIGHT_STATE_OFF", LIGHT_STATE_OFF},
         {"LIGHT_SWITCH_OFF", LIGHT_SWITCH_OFF},
+        {"LIGHT_SWITCH_ON", LIGHT_SWITCH_ON},
         {"LIGHT_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
+        {"EV_STOPPING_MODE_CREEP", EV_STOPPING_MODE_CREEP},
+        {"EV_STOPPING_MODE_ROLL", EV_STOPPING_MODE_ROLL},
+        {"EV_STOPPING_MODE_HOLD", EV_STOPPING_MODE_HOLD},
         {"MIRROR_DRIVER_LEFT_RIGHT",
          toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
 #ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index c17a2e2..80c299d 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -861,6 +861,41 @@
             ]
         },
         {
+            "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
             "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
             "defaultValue": {
                 "int32Values": [
@@ -1036,6 +1071,71 @@
             ]
         },
         {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
             "property": "VehicleProperty::SEAT_EASY_ACCESS_ENABLED",
             "defaultValue": {
                 "int32Values": [
@@ -1588,6 +1688,24 @@
             ]
         },
         {
+            "property": "VehicleProperty::EV_STOPPING_MODE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::EV_STOPPING_MODE_CREEP"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::EV_STOPPING_MODE_CREEP",
+                        "Constants::EV_STOPPING_MODE_ROLL",
+                        "Constants::EV_STOPPING_MODE_HOLD"
+                    ]
+                }
+            ]
+        },
+        {
             "property": "VehicleProperty::FUEL_LEVEL_LOW",
             "defaultValue": {
                 "int32Values": [
@@ -1982,8 +2100,8 @@
                 160,
                 280,
                 5,
-                605,
-                825,
+                600,
+                840,
                 10
             ]
         },
@@ -2707,6 +2825,23 @@
             ]
         },
         {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
             "property": "VehicleProperty::HEADLIGHTS_SWITCH",
             "defaultValue": {
                 "int32Values": [
@@ -2780,6 +2915,24 @@
             ]
         },
         {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
             "property": "VehicleProperty::EVS_SERVICE_REQUEST",
             "defaultValue": {
                 "int32Values": [
@@ -2808,6 +2961,38 @@
             }
         },
         {
+            "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DRIVER_ATTENTION_MONITORING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
             "property": "VehicleProperty::INITIAL_USER_INFO"
         },
         {
@@ -2897,6 +3082,54 @@
                     "GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1"
                 ]
             }
+        },
+        {
+            "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::BLIND_SPOT_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
         }
     ]
 }
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
index bf27c95..7275ba3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
@@ -28,6 +28,7 @@
 namespace propertyutils_impl {
 
 // These names are not part of the API since we only expose ints.
+using ::aidl::android::hardware::automotive::vehicle::EvStoppingMode;
 using ::aidl::android::hardware::automotive::vehicle::PortLocationType;
 using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaDoor;
@@ -98,7 +99,11 @@
 constexpr int LIGHT_STATE_ON = toInt(propertyutils_impl::VehicleLightState::ON);
 constexpr int LIGHT_STATE_OFF = toInt(propertyutils_impl::VehicleLightState::OFF);
 constexpr int LIGHT_SWITCH_OFF = toInt(propertyutils_impl::VehicleLightSwitch::OFF);
+constexpr int LIGHT_SWITCH_ON = toInt(propertyutils_impl::VehicleLightSwitch::ON);
 constexpr int LIGHT_SWITCH_AUTO = toInt(propertyutils_impl::VehicleLightSwitch::AUTOMATIC);
+constexpr int EV_STOPPING_MODE_CREEP = toInt(propertyutils_impl::EvStoppingMode::CREEP);
+constexpr int EV_STOPPING_MODE_ROLL = toInt(propertyutils_impl::EvStoppingMode::ROLL);
+constexpr int EV_STOPPING_MODE_HOLD = toInt(propertyutils_impl::EvStoppingMode::HOLD);
 constexpr int WHEEL_FRONT_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_FRONT);
 constexpr int WHEEL_FRONT_RIGHT = toInt(propertyutils_impl::VehicleAreaWheel::RIGHT_FRONT);
 constexpr int WHEEL_REAR_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_REAR);
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 08e1990..0915701 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -20,6 +20,7 @@
 #include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
 #include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
 #include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
+#include <aidl/android/hardware/automotive/vehicle/EvStoppingMode.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceState.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceType.h>
 #include <aidl/android/hardware/automotive/vehicle/FuelType.h>
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 5595afe..1680442 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -481,12 +481,42 @@
                             actualPropertyType);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAdaptiveCruiseControlEnabledConfig) {
+    verifyProperty(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionEnabledConfig) {
+    verifyProperty(VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverAttentionMonitoringEnabledConfig) {
+    verifyProperty(VehicleProperty::DRIVER_ATTENTION_MONITORING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
 TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBrakeRegenerationLevelConfig) {
     verifyProperty(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL,
                    VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
                    VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvStoppingModeConfig) {
+    verifyProperty(VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
 TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvCurrentBatteryCapacityConfig) {
     verifyProperty(VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ,
                    VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
@@ -547,6 +577,18 @@
                    VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsStateConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsSwitchConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
 TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoFoldEnabledConfig) {
     verifyProperty(VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE,
                    VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
@@ -559,12 +601,30 @@
                    VehicleArea::MIRROR, VehiclePropertyType::BOOLEAN);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatHeadrestHeightPosV2Config) {
+    verifyProperty(VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
 TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatWalkInPosConfig) {
     verifyProperty(VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE,
                    VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
                    VehicleArea::SEAT, VehiclePropertyType::INT32);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsStateConfig) {
+    verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsSwitchConfig) {
+    verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
 TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatEasyAccessEnabledConfig) {
     verifyProperty(VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE,
                    VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
@@ -601,6 +661,42 @@
                    VehicleArea::SEAT, VehiclePropertyType::INT32);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAutomaticEmergencyBrakingEnabledConfig) {
+    verifyProperty(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyForwardCollisionWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBlindSpotWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneDepartureWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneKeepAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
 std::vector<ServiceDescriptor> getDescriptors() {
     std::vector<ServiceDescriptor> descriptors;
     for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index e7bb282..8a80095 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -78,6 +78,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.automotive.audiocontrol</name>
+        <version>2</version>
         <interface>
             <name>IAudioControl</name>
             <instance>default</instance>
@@ -656,6 +657,13 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
+        <name>android.hardware.tv.earc</name>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
         <name>android.hardware.tv.hdmi</name>
         <interface>
             <name>IHdmi</name>
@@ -765,4 +773,12 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="native">
+        <name>mapper</name>
+        <version>1.0</version>
+        <interface>
+            <name>I</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
 </compatibility-matrix>
diff --git a/current.txt b/current.txt
index 0fb8b49..fbdd3fe 100644
--- a/current.txt
+++ b/current.txt
@@ -932,5 +932,6 @@
 # ABI preserving changes to HALs during Android U
 2aa559cda86c358c6429114ef6bc72c1b43281e98f9eb6b4df5e7073c8d05767 android.hardware.automotive.vehicle@2.0::types
 42abd285a4293dadb8c89bc63b90cae2872fbffe90c4517aa3ea4965e8aecff7 android.hardware.graphics.common@1.2::types
+4f1a02d21a22104c734f71cdbba19b6f7e93d4ee107ff79f0dbdd171a8430e0e android.hardware.automotive.vehicle@2.0::types
 
 # There will be no more HIDL HALs. Use AIDL instead.
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index fa3087a..1d01a02 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -33,6 +33,13 @@
     export_header_lib_headers: [
         "libarect_headers",
     ],
+    // TODO(b/214400477) Remove apex_available
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 }
 
 cc_library_shared {
@@ -66,6 +73,13 @@
         "libbase_headers",
         "libimapper_stablec",
     ],
+    // TODO(b/214400477) Remove apex_available
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 }
 
 cc_test {
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
index 25af6d1..102dada 100644
--- a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
@@ -566,6 +566,8 @@
 
 #undef DEFINE_TYPE
 
+#if defined(__cplusplus) && __cplusplus >= 202002L
+
 template <typename F, std::size_t... I>
 void invokeWithStandardMetadata(F&& f, StandardMetadataType type, std::index_sequence<I...>) {
     // Setup the jump table, mapping from each type to a springboard that invokes the template
@@ -620,4 +622,6 @@
     return retVal;
 }
 
+#endif
+
 }  // namespace android::hardware::graphics::mapper
\ No newline at end of file
diff --git a/secure_element/aidl/default/main.cpp b/secure_element/aidl/default/main.cpp
index 16b8236..9b5a8fc 100644
--- a/secure_element/aidl/default/main.cpp
+++ b/secure_element/aidl/default/main.cpp
@@ -15,141 +15,673 @@
  */
 
 #include <aidl/android/hardware/secure_element/BnSecureElement.h>
-
 #include <android-base/hex.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 
+#include <algorithm>
+
 using aidl::android::hardware::secure_element::BnSecureElement;
 using aidl::android::hardware::secure_element::ISecureElementCallback;
 using aidl::android::hardware::secure_element::LogicalChannelResponse;
 using android::base::HexString;
 using ndk::ScopedAStatus;
 
-static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
-                                                     0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
-                                                     0x43, 0x54, 0x53, 0x31};
-static const std::vector<uint8_t> kLongAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
-                                                         0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
-                                                         0x43, 0x54, 0x53, 0x32};
+static const std::vector<uint8_t> kIssuerSecurityDomainSelectResponse = {0x00, 0x00, 0x90, 0x00};
 
-class MySecureElement : public BnSecureElement {
+namespace se {
+// Application identifier.
+using Aid = std::vector<uint8_t>;
+
+// ISO7816 APDU status codes.
+enum Status : uint16_t {
+    SW_WRONG_DATA = 0x6A80,
+    SW_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881,
+    SW_CONDITIONS_NOT_SATISFIED = 0x6985,
+    SW_INCORRECT_P1P2 = 0x6A86,
+    SW_BYTES_REMAINING_00 = 0x6100,
+    SW_WRONG_LENGTH = 0x6700,
+    SW_CORRECT_LENGTH_00 = 0x6C00,
+    SW_INS_NOT_SUPPORTED = 0x6D00,
+    SW_NO_ERROR = 0x9000,
+};
+
+// Type for raw APDUs.
+using RawApdu = std::vector<uint8_t>;
+
+// Wrap a command APDU (Application Processing Data Unit) to provide
+// accessors for header fields.
+struct Apdu {
   public:
-    ScopedAStatus closeChannel(int8_t channelNumber) override {
-        LOG(INFO) << __func__ << " channel number: " << channelNumber;
-        return ScopedAStatus::ok();
+    // Construct a command Apdu.
+    Apdu(std::vector<uint8_t> packet) : bytes_(std::move(packet)) {
+        CHECK(bytes_.size() >= kHeaderSize) << "command APDU created with invalid length";
+        size_t payload_len = bytes_.size() - kHeaderSize;
+
+        // TODO(b/123254068) - add support for extended command APDUs.
+        // Pre compute Lc and Le.
+
+        // Case 1: CLA | INS | P1 | P2
+        if (payload_len == 0) {
+            lc_ = 0;
+            le_ = 0;
+            return;
+        }
+
+        // Case 2: CLA | INS | P1 | P2 | Le
+        // Le has a value of 1 to 255.
+        if (payload_len == 1) {
+            le_ = bytes_[kHeaderSize];
+            le_ = le_ == 0 ? 256 : le_;
+            lc_ = 0;
+            return;
+        }
+
+        // Case 3: CLA | INS | P1 | P2 | Lc | Data
+        // Lc is less than 256 bytes
+        // of data, and Le is zero.
+        lc_ = bytes_[kHeaderSize];
+        if (payload_len <= (1 + lc_)) {
+            le_ = 0;
+        }
+
+        // Case 4: CLA | INS | P1 | P2 | Lc | Data | Le
+        // The legacy Case 4. Lc and Le
+        // are less than 256 bytes of data.
+        else {
+            le_ = bytes_[bytes_.size() - 1];
+            le_ = le_ == 0 ? 256 : le_;
+        }
     }
-    ScopedAStatus getAtr(std::vector<uint8_t>* _aidl_return) override {
-        LOG(INFO) << __func__;
-        _aidl_return->clear();
-        return ScopedAStatus::ok();
+
+    // Construct a response Apdu with data.
+    static RawApdu CreateResponse(std::vector<uint8_t> data, Status status) {
+        // Append status word.
+        data.push_back(status >> 8);
+        data.push_back(status);
+        return data;
     }
+
+    // Construct a response Apdu with no data.
+    static RawApdu CreateResponse(Status status) {
+        // Append status word.
+        return std::vector<uint8_t>{static_cast<uint8_t>(status >> 8),
+                                    static_cast<uint8_t>(status)};
+    }
+
+    // Return if command APDU is extended.
+    // The ISO/IEC 7816-4:2013 specification defines an extended APDU as any APDU
+    // whose payload data, response data or expected data length exceeds the 256
+    // byte limit.
+    bool IsExtended() const { return (bytes_.size() - kHeaderSize) > 256; }
+
+    // Return if command APDU has payload bytes.
+    bool HasPayload() const { return bytes_.size() > kHeaderSize; }
+
+    uint8_t get_cla() const { return bytes_[0]; }
+    uint8_t get_ins() const { return bytes_[1]; }
+    uint8_t get_p1() const { return bytes_[2]; }
+    uint8_t get_p2() const { return bytes_[3]; }
+
+    // Return the channel number encoded in the CLA field.
+    uint8_t get_channel_number() const {
+        // Type 4 commands — Encode legacy ISO/IEC 7816-4 logical channel
+        // information. Type 16 commands — Defined by the ISO/IEC 7816-4:2013
+        // specification to
+        //   encode information for additional 16 logical channels in the card.
+        uint8_t cla = get_cla();
+        return (cla & 0x40) == 0 ? cla & 0x3 : 4 + (cla & 0xf);
+    }
+
+    // Return the length of the command data field.
+    uint16_t get_lc() const { return lc_; }
+
+    // Return the expected length of the response data field.
+    // Le should be have the same format as Lc.
+    uint16_t get_le() const { return le_; }
+
+    // Get the pointer to the APDU raw data.
+    std::vector<uint8_t> const& get_data() const { return bytes_; }
+
+  private:
+    // Size of command header, including CLA, INS, P1, P2 fields.
+    const size_t kHeaderSize = 4;
+
+    // Command or response buffer.
+    std::vector<uint8_t> bytes_{};
+
+    // Lengths of command data field and expected response data field.
+    uint16_t lc_{0};
+    uint16_t le_{0};
+};
+
+// Type of SE applets.
+class Applet {
+  public:
+    virtual ~Applet() {}
+
+    // Called to inform this applet that it has been selected.
+    virtual RawApdu Select(Aid const& aid, uint8_t p2) = 0;
+
+    // Called by the Java Card runtime environment to process an
+    // incoming APDU command. SELECT commands are processed by \ref select
+    // instead.
+    virtual RawApdu Process(Apdu const& apdu) = 0;
+};
+};  // namespace se
+
+// Implement the Google-eSE-test.cap test applet for passing OMAPI CTS tests
+// on Cuttlefish. The reference can be found here:
+// cts/tests/tests/secure_element/sample_applet/src/com/android/cts/omapi/test/CtsAndroidOmapiTestApplet.java
+class CtsAndroidOmapiTestApplet : public se::Applet {
+  public:
+    CtsAndroidOmapiTestApplet() {}
+    virtual ~CtsAndroidOmapiTestApplet() {}
+
+    se::RawApdu Select(se::Aid const& aid, uint8_t /*p2*/) override {
+        if (aid[aid.size() - 1] == 0x31) {
+            // AID: A000000476416E64726F696443545331
+            return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
+        } else {
+            // AID: A000000476416E64726F696443545332
+            return se::Apdu::CreateResponse(GenerateBerTLVBytes(SELECT_RESPONSE_DATA_LENGTH),
+                                            se::Status::SW_NO_ERROR);
+        }
+    }
+
+    se::RawApdu ReadNextResponseChunk(uint16_t max_output_len) {
+        uint16_t output_len = static_cast<uint16_t>(response_.size() - response_offset_);
+        output_len = std::min<uint16_t>(max_output_len, output_len);
+        std::vector<uint8_t> output{
+                &response_[response_offset_],
+                &response_[response_offset_ + output_len],
+        };
+        response_offset_ += output_len;
+        uint16_t remaining_len = response_.size() - response_offset_;
+        se::Status status = se::Status::SW_NO_ERROR;
+        if (remaining_len > 0) {
+            if (remaining_len > 256) {
+                remaining_len = 0x00;
+            }
+            status = se::Status(se::Status::SW_BYTES_REMAINING_00 | remaining_len);
+        } else {
+            response_.clear();
+            response_offset_ = 0;
+        }
+        return se::Apdu::CreateResponse(output, status);
+    }
+
+    se::RawApdu Process(se::Apdu const& apdu) override {
+        uint16_t lc;
+        uint16_t le = apdu.get_le();
+        uint8_t p1 = apdu.get_p1();
+        uint8_t p2 = apdu.get_p2();
+
+        switch (apdu.get_ins()) {
+            case NO_DATA_INS_1:
+            case NO_DATA_INS_2:
+                LOG(INFO) << __func__ << ": NO_DATA_INS_1|2";
+                return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
+
+            case DATA_INS_1:
+            case DATA_INS_2:
+                // Return 256 bytes of data.
+                LOG(INFO) << __func__ << ": DATA_INS_1|2";
+                return se::Apdu::CreateResponse(GeneratesBytes(256), se::Status::SW_NO_ERROR);
+
+            case GET_RESPONSE_INS:
+                // ISO GET_RESPONSE command.
+                LOG(INFO) << __func__ << ": GET_RESPONSE_INS";
+                if (response_.empty()) {
+                    return se::Apdu::CreateResponse(se::Status::SW_CONDITIONS_NOT_SATISFIED);
+                }
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case SW_62xx_APDU_INS:
+                LOG(INFO) << __func__ << ": SW_62xx_APDU_INS";
+                if (p1 < 1 || p1 > 16) {
+                    return se::Apdu::CreateResponse(se::Status::SW_INCORRECT_P1P2);
+                }
+                if (p2 == SW_62xx_DATA_APDU_P2) {
+                    return se::Apdu::CreateResponse(GeneratesBytes(3),
+                                                    se::Status(SW_62xx_resp[p1 - 1]));
+                }
+                if (p2 == SW_62xx_VALIDATE_DATA_P2) {
+                    std::vector<uint8_t> output{SW_62xx_VALIDATE_DATA_RESP.begin(),
+                                                SW_62xx_VALIDATE_DATA_RESP.end()};
+                    output[2] = p1;
+                    return se::Apdu::CreateResponse(std::move(output),
+                                                    se::Status(SW_62xx_resp[p1 - 1]));
+                }
+                return se::Apdu::CreateResponse(se::Status(SW_62xx_resp[p1 - 1]));
+
+            case SEGMENTED_RESP_INS_1:
+            case SEGMENTED_RESP_INS_2:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_1|2";
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(std::min<uint16_t>(apdu.get_le(), 256));
+
+            case SEGMENTED_RESP_INS_3:
+            case SEGMENTED_RESP_INS_4:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_3|4";
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case SEGMENTED_RESP_INS_5:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_5";
+                if (le == 0xff) {
+                    return se::Apdu::CreateResponse(
+                            se::Status(se::Status::SW_CORRECT_LENGTH_00 | 0xff));
+                }
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case CHECK_SELECT_P2_APDU:
+                LOG(INFO) << __func__ << ": CHECK_SELECT_P2_APDU";
+                return se::Apdu::CreateResponse(std::vector<uint8_t>{apdu.get_p2()},
+                                                se::Status::SW_NO_ERROR);
+
+            default:
+                // Case is not known.
+                LOG(INFO) << __func__ << ": UNKNOWN_INS";
+                return se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
+        }
+    }
+
+  private:
+    std::vector<uint8_t> response_{};
+    uint16_t response_offset_{0};
+
+    static const uint8_t NO_DATA_INS_1 = 0x06;
+    static const uint8_t NO_DATA_INS_2 = 0x0A;
+    static const uint8_t DATA_INS_1 = 0x08;
+    static const uint8_t DATA_INS_2 = 0x0C;
+    static const uint8_t SW_62xx_APDU_INS = 0xF3;
+    static const uint8_t SW_62xx_DATA_APDU_P2 = 0x08;
+    static const uint8_t SW_62xx_VALIDATE_DATA_P2 = 0x0C;
+
+    static constexpr std::array<uint8_t, 7> SW_62xx_VALIDATE_DATA_RESP = {0x01, 0xF3, 0x00, 0x0C,
+                                                                          0x01, 0xAA, 0x00};
+    static constexpr uint16_t SW_62xx_resp[] = {
+            0x6200, 0x6281, 0x6282, 0x6283, 0x6285, 0x62F1, 0x62F2, 0x63F1,
+            0x63F2, 0x63C2, 0x6202, 0x6280, 0x6284, 0x6286, 0x6300, 0x6381,
+    };
+
+    static const uint8_t SEGMENTED_RESP_INS_1 = 0xC2;
+    static const uint8_t SEGMENTED_RESP_INS_2 = 0xC4;
+    static const uint8_t SEGMENTED_RESP_INS_3 = 0xC6;
+    static const uint8_t SEGMENTED_RESP_INS_4 = 0xC8;
+    static const uint8_t SEGMENTED_RESP_INS_5 = 0xCF;
+    static const uint8_t CHECK_SELECT_P2_APDU = 0xF4;
+    static const uint8_t GET_RESPONSE_INS = 0xC0;
+    static const uint8_t BER_TLV_TYPE = 0x1F;
+    static const uint16_t SELECT_RESPONSE_DATA_LENGTH = 252;
+
+    static const uint16_t LENGTH_256 = 0x0100;
+    static constexpr std::array<uint8_t, 256> resp_bytes256{
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+            0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+            0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+            0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
+            0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+            0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
+            0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
+            0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
+            0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+            0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+            0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
+            0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3,
+            0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1,
+            0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+            0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
+            0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB,
+            0xFC, 0xFD, 0xFE, 0xFF};
+
+    // Generate a response buffer of the selected length containing valid
+    // BER TLV bytes.
+    static std::vector<uint8_t> GenerateBerTLVBytes(uint16_t le) {
+        // Support length from 0x00 - 0x7FFF.
+        uint16_t le_len = 1;
+        if (le < (uint16_t)0x80) {
+            le_len = 1;
+        } else if (le < (uint16_t)0x100) {
+            le_len = 2;
+        } else {
+            le_len = 3;
+        }
+
+        uint16_t total_len = (uint16_t)(le + 2 + le_len);
+        std::vector<uint8_t> output(total_len);
+        uint16_t i = 0;
+
+        output[i++] = BER_TLV_TYPE;
+        output[i++] = 0x00;  // second byte of Type
+        if (le < 0x80) {
+            output[i++] = le;
+        } else if (le < 0x100) {
+            output[i++] = 0x81;
+            output[i++] = le;
+        } else {
+            output[i++] = 0x82;
+            output[i++] = (le >> 8);
+            output[i++] = (le & 0xFF);
+        }
+        while (i < total_len) {
+            output[i++] = ((i - 2 - le_len) & 0xFF);
+        }
+
+        // Set the last byte to 0xFF for CTS validation.
+        output[total_len - 1] = 0xFF;
+        return output;
+    }
+
+    // Generate a response buffer of the selected length using the
+    // array resp_bytes256 as input.
+    static std::vector<uint8_t> GeneratesBytes(uint16_t total_len) {
+        std::vector<uint8_t> output(total_len);
+        uint16_t i = 0;
+
+        while (i < total_len) {
+            if ((total_len - i) >= resp_bytes256.size()) {
+                std::memcpy(&output[i], resp_bytes256.data(), resp_bytes256.size());
+                i += resp_bytes256.size();
+            } else {
+                output[i] = i & 0xFF;
+                i += 1;
+            }
+        }
+
+        // Set the last byte to 0xFF for CTS validation.
+        output[total_len - 1] = 0xFF;
+        return output;
+    }
+};
+
+class EmulatedSecureElement : public BnSecureElement {
+  public:
+    EmulatedSecureElement() {
+        std::shared_ptr<CtsAndroidOmapiTestApplet> test_applet =
+                std::make_shared<CtsAndroidOmapiTestApplet>();
+
+        applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
+                                             0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31},
+                                     test_applet});
+
+        applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
+                                             0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x32},
+                                     test_applet});
+    }
+
     ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& clientCallback) override {
         LOG(INFO) << __func__ << " callback: " << clientCallback.get();
         if (!clientCallback) {
             return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
         }
-        mCb = clientCallback;
-        mCb->onStateChange(true, "");
+        client_callback_ = clientCallback;
+        client_callback_->onStateChange(true, "init");
         return ScopedAStatus::ok();
     }
-    ScopedAStatus isCardPresent(bool* _aidl_return) override {
+
+    ScopedAStatus getAtr(std::vector<uint8_t>* aidl_return) override {
         LOG(INFO) << __func__;
-        *_aidl_return = true;
+        *aidl_return = atr_;
         return ScopedAStatus::ok();
     }
+
+    ScopedAStatus reset() override {
+        LOG(INFO) << __func__;
+        CHECK(client_callback_ != nullptr) << " init not invoked";
+        client_callback_->onStateChange(false, "reset");
+        client_callback_->onStateChange(true, "reset");
+        // All channels are closed after reset.
+        for (auto channel : channels_) {
+            channel = Channel();
+        }
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus isCardPresent(bool* aidl_return) override {
+        LOG(INFO) << __func__;
+        *aidl_return = true;
+        return ScopedAStatus::ok();
+    }
+
     ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
-                                   std::vector<uint8_t>* _aidl_return) override {
+                                   std::vector<uint8_t>* aidl_return) override {
         LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
                   << ") p2 " << p2;
 
-        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
-        // The functionality here is enough to exercise the framework, but actual
-        // calls to the secure element will fail. This implementation does not model
-        // channel isolation or any other aspects important to implementing secure element.
-        *_aidl_return = {0x90, 0x00, 0x00};  // DO NOT COPY
+        std::vector<uint8_t> select_response;
+        std::shared_ptr<se::Applet> applet = nullptr;
+
+        // The basic channel can only be opened once, and stays opened
+        // and locked until the channel is closed.
+        if (channels_[0].opened) {
+            LOG(INFO) << __func__ << " basic channel already opened";
+            return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
+        }
+
+        // If the AID is defined (the AID is not Null and the length of the
+        // AID is not 0) and the channel is not locked then the corresponding
+        // applet shall be selected.
+        if (aid.size() > 0) {
+            applet = SelectApplet(aid);
+            if (applet == nullptr) {
+                // No applet registered with matching AID.
+                LOG(INFO) << __func__ << " basic channel AID not found";
+                return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+            }
+            select_response = applet->Select(aid, p2);
+        }
+
+        // If the AID is a 0 length AID and the channel is not locked, the
+        // method will select the Issuer Security Domain of the SE by sending a
+        // SELECT command with a 0 length AID as defined in
+        // [GP Card specification].
+        if (aid.size() == 0) {
+            select_response = kIssuerSecurityDomainSelectResponse;
+        }
+
+        LOG(INFO) << __func__ << " sending response: "
+                  << HexString(select_response.data(), select_response.size());
+
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[0] = Channel(aid, p2, applet);
+        *aidl_return = select_response;
         return ScopedAStatus::ok();
     }
+
     ScopedAStatus openLogicalChannel(
             const std::vector<uint8_t>& aid, int8_t p2,
-            ::aidl::android::hardware::secure_element::LogicalChannelResponse* _aidl_return)
+            ::aidl::android::hardware::secure_element::LogicalChannelResponse* aidl_return)
             override {
         LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
                   << ") p2 " << p2;
 
-        if (aid != kAndroidTestAid && aid != kLongAndroidTestAid) {
-            return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+        size_t channel_number = 1;
+        std::vector<uint8_t> select_response;
+        std::shared_ptr<se::Applet> applet = nullptr;
+
+        // Look for an available channel number.
+        for (; channel_number < channels_.size(); channel_number++) {
+            if (channels_[channel_number].opened == false) {
+                break;
+            }
         }
 
-        *_aidl_return = LogicalChannelResponse{.channelNumber = 1, .selectResponse = {}};
+        // All channels are currently allocated.
+        if (channel_number >= channels_.size()) {
+            LOG(INFO) << __func__ << " all logical channels already opened";
+            return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
+        }
 
-        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
-        // The functionality here is enough to exercise the framework, but actual
-        // calls to the secure element will fail. This implementation does not model
-        // channel isolation or any other aspects important to implementing secure element.
-        if (aid == kAndroidTestAid) {                                 // DO NOT COPY
-            size_t size = 2050;                                       // DO NOT COPY
-            _aidl_return->selectResponse.resize(size);                // DO NOT COPY
-            _aidl_return->selectResponse[size - 1] = 0x00;            // DO NOT COPY
-            _aidl_return->selectResponse[size - 2] = 0x90;            // DO NOT COPY
-        } else {                                                      // DO NOT COPY
-            _aidl_return->selectResponse = {0x00, 0x00, 0x90, 0x00};  // DO NOT COPY
-        }                                                             // DO NOT COPY
+        // If the AID is defined (the AID is not Null and the length of the
+        // AID is not 0) then the corresponding applet shall be selected.
+        if (aid.size() > 0) {
+            applet = SelectApplet(aid);
+            if (applet == nullptr) {
+                // No applet registered with matching AID.
+                LOG(INFO) << __func__ << " logical channel AID not found";
+                return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+            }
+            select_response = applet->Select(aid, p2);
+        }
+
+        // If the length of the AID is 0, the method will select the
+        // Issuer Security Domain of the SE by sending a SELECT command
+        // with 0 length AID as defined in [GPCS].
+        if (aid.size() == 0) {
+            select_response = kIssuerSecurityDomainSelectResponse;
+        }
 
         LOG(INFO) << __func__ << " sending response: "
-                  << HexString(_aidl_return->selectResponse.data(),
-                               _aidl_return->selectResponse.size());
+                  << HexString(select_response.data(), select_response.size());
 
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[channel_number] = Channel(aid, p2, applet);
+        *aidl_return = LogicalChannelResponse{
+                .channelNumber = static_cast<int8_t>(channel_number),
+                .selectResponse = select_response,
+        };
         return ScopedAStatus::ok();
     }
-    ScopedAStatus reset() override {
-        LOG(INFO) << __func__;
-        mCb->onStateChange(false, "reset");
-        mCb->onStateChange(true, "reset");
+
+    ScopedAStatus closeChannel(int8_t channel_number) override {
+        LOG(INFO) << __func__ << " channel number: " << static_cast<int>(channel_number);
+        // The selected basic or logical channel is not opened.
+        if (channel_number >= channels_.size() || !channels_[channel_number].opened) {
+            return ScopedAStatus::ok();
+        }
+
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[channel_number].opened = false;
         return ScopedAStatus::ok();
     }
+
     ScopedAStatus transmit(const std::vector<uint8_t>& data,
-                           std::vector<uint8_t>* _aidl_return) override {
+                           std::vector<uint8_t>* aidl_return) override {
         LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
                   << data.size() << ")";
 
-        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
-        // The functionality here is enough to exercise the framework, but actual
-        // calls to the secure element will fail. This implementation does not model
-        // channel isolation or any other aspects important to implementing secure element.
+        se::Apdu apdu(data);
+        uint8_t channel_number = apdu.get_channel_number();
+        std::vector<uint8_t> response_apdu;
 
-        std::string hex = HexString(data.data(), data.size());                    // DO NOT COPY
-        if (hex == "01a4040210a000000476416e64726f696443545331") {                // DO NOT COPY
-            *_aidl_return = {0x00, 0x6A, 0x00};                                   // DO NOT COPY
-        } else if (data == std::vector<uint8_t>{0x00, 0xF4, 0x00, 0x00, 0x00}) {  // DO NOT COPY
-            // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
-            *_aidl_return = {0x00, 0x90, 0x00};                                   // DO NOT COPY
-        } else if (data == std::vector<uint8_t>{0x01, 0xF4, 0x00, 0x00, 0x00}) {  // DO NOT COPY
-            // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
-            *_aidl_return = {0x00, 0x90, 0x00};             // DO NOT COPY
-        } else if (data.size() == 5 || data.size() == 8) {  // DO NOT COPY
-            // SEGMENTED_RESP_APDU - happens to use length 5 and 8 // DO NOT COPY
-            size_t size = (data[2] << 8 | data[3]) + 2;       // DO NOT COPY
-            _aidl_return->resize(size);                       // DO NOT COPY
-            (*_aidl_return)[size - 1] = 0x00;                 // DO NOT COPY
-            (*_aidl_return)[size - 2] = 0x90;                 // DO NOT COPY
-            if (size >= 3) (*_aidl_return)[size - 3] = 0xFF;  // DO NOT COPY
-        } else {                                              // DO NOT COPY
-            *_aidl_return = {0x90, 0x00, 0x00};               // DO NOT COPY
-        }                                                     // DO NOT COPY
+        switch (apdu.get_ins()) {
+            // TODO(b/123254068) - Implement support channel management APDUs.
+            case MANAGE_CHANNEL_INS:
+                // P1 = '00' to open
+                // P1 = '80' to close
+                LOG(INFO) << __func__ << " MANAGE_CHANNEL apdu";
+                response_apdu =
+                        se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                break;
 
+            // TODO(b/123254068) - Implement support channel management APDUs.
+            case SELECT_INS:
+                LOG(INFO) << __func__ << " SELECT apdu";
+                response_apdu =
+                        se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                break;
+
+            default:
+                CHECK(channel_number < channels_.size()) << " invalid channel number";
+                if (!channels_[channel_number].opened) {
+                    LOG(INFO) << __func__ << " the channel " << static_cast<int>(channel_number)
+                              << " is not opened";
+                    response_apdu =
+                            se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                    break;
+                }
+                // Send the APDU to the applet for processing.
+                // Applet implementation is optional, default to sending
+                // SW_INS_NOT_SUPPORTED.
+                if (channels_[channel_number].applet == nullptr) {
+                    response_apdu = se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
+                } else {
+                    response_apdu = channels_[channel_number].applet->Process(apdu);
+                }
+                break;
+        }
+
+        aidl_return->assign(response_apdu.begin(), response_apdu.end());
+        LOG(INFO) << __func__
+                  << " response: " << HexString(aidl_return->data(), aidl_return->size()) << " ("
+                  << aidl_return->size() << ")";
         return ScopedAStatus::ok();
     }
 
   private:
-    std::shared_ptr<ISecureElementCallback> mCb;
+    struct Channel {
+      public:
+        Channel() = default;
+        Channel(Channel const&) = default;
+        Channel(se::Aid const& aid, uint8_t p2, std::shared_ptr<se::Applet> applet)
+            : opened(true), aid(aid), p2(p2), applet(std::move(applet)) {}
+        Channel& operator=(Channel const&) = default;
+
+        bool opened{false};
+        se::Aid aid{};
+        uint8_t p2{0};
+        std::shared_ptr<se::Applet> applet{nullptr};
+    };
+
+    // OMAPI abstraction.
+
+    // Channel 0 is the basic channel, channels 1-19 are the logical channels.
+    std::array<Channel, 20> channels_{};
+    std::shared_ptr<ISecureElementCallback> client_callback_;
+
+    // Secure element abstraction.
+
+    static const uint8_t MANAGE_CHANNEL_INS = 0x70;
+    static const uint8_t SELECT_INS = 0xa4;
+
+    // Secure element ATR (Answer-To-Reset).
+    // The format is specified by ISO/IEC 1816-4 2020 and lists
+    // the capabilities of the card.
+    //
+    // TODO(b/123254068): encode the default SE properties in the ATR:
+    // support for extended Lc / Le fields, maximum number of logical channels.
+    // The CTS tests are *not* checking this value.
+    std::vector<uint8_t> const atr_{};
+
+    // Applet registration.
+    std::vector<std::pair<se::Aid, std::shared_ptr<se::Applet>>> applets_{};
+
+    // Return the first applet that matches the selected aid.
+    std::shared_ptr<se::Applet> SelectApplet(se::Aid const& aid) {
+        for (auto& [applet_aid, applet] : applets_) {
+            if (applet_aid == aid) {
+                return applet;
+            }
+        }
+        return nullptr;
+    }
 };
 
 int main() {
     ABinderProcess_setThreadPoolMaxThreadCount(0);
 
-    auto se = ndk::SharedRefBase::make<MySecureElement>();
+    auto se = ndk::SharedRefBase::make<EmulatedSecureElement>();
     const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
     binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
     CHECK_EQ(status, STATUS_OK);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 342b926..2440977 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1136,8 +1136,8 @@
  * that has been generated using an associate IRemotelyProvisionedComponent.
  */
 TEST_P(NewKeyGenerationTest, RsaWithRkpAttestation) {
-    if (AidlVersion() < 2) {
-        GTEST_SKIP() << "Only required starting with KeyMint v2";
+    if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
+        GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
     }
 
     // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
@@ -1214,8 +1214,8 @@
  * that has been generated using an associate IRemotelyProvisionedComponent.
  */
 TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
-    if (AidlVersion() < 2) {
-        GTEST_SKIP() << "Only required starting with KeyMint v2";
+    if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
+        GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
     }
 
     // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 5485db3..c506667 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -115,11 +115,9 @@
 interface IRemotelyProvisionedComponent {
     const int STATUS_FAILED = 1;
     const int STATUS_INVALID_MAC = 2;
-    // --------- START: Versions 1 and 2 Only ----------
-    const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
+    const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3; // Versions 1 and 2 Only
     const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
-    const int STATUS_INVALID_EEK = 5;
-    // --------- END: Versions 1 and 2 Only ------------
+    const int STATUS_INVALID_EEK = 5; // Versions 1 and 2 Only
     const int STATUS_REMOVED = 6;
 
     /**
@@ -347,8 +345,8 @@
      *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
      *     unprotected: {},
      *     payload: bstr .cbor Data / nil,
-     *     signature: bstr      ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<Data>) /
-     *                          ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<Data>)
+     *     signature: bstr      ; PureEd25519(CDI_Leaf_Priv, SignedDataSigStruct<Data>) /
+     *                          ; ECDSA(CDI_Leaf_Priv, SignedDataSigStruct<Data>)
      * ]
      *
      * ; Sig_structure for SignedData
@@ -427,8 +425,8 @@
      *     protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
      *     unprotected: {},
      *     payload: bstr .cbor DiceChainEntryPayload,
-     *     signature: bstr ; PureEd25519(SigningKey, bstr .cbor DiceChainEntryInput) /
-     *                     ; ECDSA(SigningKey, bstr .cbor DiceChainEntryInput)
+     *     signature: bstr ; PureEd25519(SigningKey, DiceChainEntryInput) /
+     *                     ; ECDSA(SigningKey, DiceChainEntryInput)
      *                     ; See RFC 8032 for details of how to encode the signature value
      *                     ; for Ed25519.
      * ]
@@ -442,12 +440,6 @@
      *
      * ; 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
-     *     -2 : bstr                    ; Sender X25519 public key
-     * }
-     *
      * PubKeyEd25519 = {                ; COSE_Key
      *     1 : 1,                       ; Key type : octet key pair
      *     3 : AlgorithmEdDSA,          ; Algorithm : EdDSA
@@ -455,13 +447,6 @@
      *     -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
-     * }
-     *
      * PubKeyECDSA256 = {               ; COSE_Key
      *     1 : 2,                       ; Key type : EC2
      *     3 : AlgorithmES256,          ; Algorithm : ECDSA w/ SHA-256
diff --git a/sensors/1.0/default/OWNERS b/sensors/1.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/2.0/default/OWNERS b/sensors/2.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.0/multihal/OWNERS b/sensors/2.0/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.0/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/2.1/default/OWNERS b/sensors/2.1/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.1/multihal/OWNERS b/sensors/2.1/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.1/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/common/vts/OWNERS b/sensors/OWNERS
similarity index 83%
rename from sensors/common/vts/OWNERS
rename to sensors/OWNERS
index 1b9a2f8..e7ebd3e 100644
--- a/sensors/common/vts/OWNERS
+++ b/sensors/OWNERS
@@ -1,5 +1,5 @@
 # Bug component: 62965
-# Sensors team
+
 arthuri@google.com
 bduddie@google.com
 stange@google.com
diff --git a/sensors/aidl/default/OWNERS b/sensors/aidl/default/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/vts/OWNERS b/sensors/aidl/vts/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/aidl/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/default/2.X/OWNERS b/sensors/common/default/2.X/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/default/2.X/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/utils/OWNERS b/sensors/common/utils/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/utils/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/vts/utils/OWNERS b/sensors/common/vts/utils/OWNERS
deleted file mode 100644
index 892da15..0000000
--- a/sensors/common/vts/utils/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
diff --git a/tv/earc/aidl/Android.bp b/tv/earc/aidl/Android.bp
new file mode 100644
index 0000000..5db6032
--- /dev/null
+++ b/tv/earc/aidl/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.earc",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/earc/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+}
diff --git a/tv/earc/aidl/OWNERS b/tv/earc/aidl/OWNERS
new file mode 100644
index 0000000..d9c6783
--- /dev/null
+++ b/tv/earc/aidl/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 826094
+include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
new file mode 100644
index 0000000..552bb46
--- /dev/null
+++ b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.earc;
+@VintfStability
+interface IEArc {
+  void setEArcEnabled(in boolean enabled);
+  boolean isEArcEnabled();
+  void setCallback(in android.hardware.tv.earc.IEArcCallback callback);
+  android.hardware.tv.earc.IEArcStatus getState(in int portId);
+  byte[] getLastReportedAudioCapabilities(in int portId);
+}
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
new file mode 100644
index 0000000..ef99824
--- /dev/null
+++ b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.earc;
+@VintfStability
+interface IEArcCallback {
+  oneway void onStateChange(in android.hardware.tv.earc.IEArcStatus status, in int portId);
+  oneway void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
+}
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
new file mode 100644
index 0000000..729c657
--- /dev/null
+++ b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.earc;
+@Backing(type="byte") @VintfStability
+enum IEArcStatus {
+  STATUS_IDLE = 0,
+  STATUS_EARC_PENDING = 1,
+  STATUS_ARC_PENDING = 2,
+  STATUS_EARC_CONNECTED = 3,
+}
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
new file mode 100644
index 0000000..3679d3b
--- /dev/null
+++ b/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.earc;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl b/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
new file mode 100644
index 0000000..bb8dabf
--- /dev/null
+++ b/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.earc;
+
+import android.hardware.tv.earc.IEArcCallback;
+import android.hardware.tv.earc.IEArcStatus;
+
+/**
+ * eARC HAL interface definition
+ */
+@VintfStability
+interface IEArc {
+    /**
+     * Function to enable or disable eARC in the device's driver and HAL. If enabled, the driver and
+     * HAL shall attempt to establish an eARC connection and inform the Android framework about
+     * updates with IEArcCallback callbacks. If disabled, the driver and HAL shall not attempt to
+     * establish an eARC connection and shall not send any IEArcCallback callbacks to the Android
+     * framework.
+     * The error status is set to
+     *         {@code SUCCESS} if the setting could be changed to the value passed.
+     *         {@code FAILURE_NOT_SUPPORTED} if the setting is not supported.
+     *         {@code FAILURE_INVALID_ARGS} if the setting value is invalid.
+     *         {@code FAILURE_UNKNOWN} if there was an unknown failure.
+     */
+    void setEArcEnabled(in boolean enabled);
+
+    /**
+     * Function to check if eARC is enabled in the device's driver and HAL.
+     */
+    boolean isEArcEnabled();
+
+    /**
+     * Function to set callback that the HAL will use to notify the system of connection state
+     * changes and capabilities of connected devices.
+     *
+     * @param callback The callback object to pass the events to the system. A previously registered
+     *        callback should be replaced by this new object. If callback is {@code null} the
+     *        previously registered callback should be deregistered.
+     */
+    void setCallback(in IEArcCallback callback);
+
+    /**
+     * Getter for the current eARC state of a port.
+     *
+     * @param portId The port ID for which the state is to be reported.
+     * @return The state of the port.
+     */
+    IEArcStatus getState(in int portId);
+
+    /**
+     * Getter for the most recent capabilities reported by the device connected to port.
+     *
+     * @param portId The port ID on which the device is connected.
+     * @return The raw, unparsed audio capabilities
+     */
+    byte[] getLastReportedAudioCapabilities(in int portId);
+}
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl b/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
new file mode 100644
index 0000000..c70191f
--- /dev/null
+++ b/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.earc;
+
+import android.hardware.tv.earc.IEArcStatus;
+
+/**
+ * eARC HAL callback methods
+ */
+@VintfStability
+oneway interface IEArcCallback {
+    /**
+     * The callback function that must be called by the eARC driver and HAL implementation to notify
+     * the Android framework of an eARC status change.
+     * @param status The new status of the port
+     * @param portId The port ID for which the state change is being reported
+     */
+    void onStateChange(in IEArcStatus status, in int portId);
+
+    /**
+     * The callback function that must be called by the eARC driver and HAL implementation to
+     * notify the Android framework of the audio capabilities reported by the connected device. On
+     * every state change to {@code STATUS_EARC_CONNECTED}, the driver shall read the capabilities
+     * reported by the eARC RX. The onStateChange callback shall always be invoked first and the
+     * onCapabilitiesReported callback shall be invoked second.
+     * @param rawCapabilities The raw unparsed audio capabilities (Ref "Section 9.5.3.6 - eARC RX
+     *         Capabilities Data Structure" in HDMI 2.1 specification).
+     * @param portId The port ID for which the audio capabilities are being reported
+     */
+    void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
+}
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl b/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
new file mode 100644
index 0000000..ecb1c85
--- /dev/null
+++ b/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.earc;
+
+/**
+ * eARC HAL connection states
+ */
+@VintfStability
+@Backing(type="byte")
+enum IEArcStatus {
+    STATUS_IDLE = 0,
+    STATUS_EARC_PENDING = 1,
+    STATUS_ARC_PENDING = 2,
+    STATUS_EARC_CONNECTED = 3,
+}
diff --git a/tv/earc/aidl/android/hardware/tv/earc/Result.aidl b/tv/earc/aidl/android/hardware/tv/earc/Result.aidl
new file mode 100644
index 0000000..054518a
--- /dev/null
+++ b/tv/earc/aidl/android/hardware/tv/earc/Result.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.earc;
+
+/**
+ * Result enum for return values. Used by the HDMI related AIDL.
+ */
+@VintfStability
+enum Result {
+    /**
+     * The eARC enabled setting was set successfully.
+     */
+    SUCCESS = 0,
+
+    /**
+     * The eARC enabled setting could not be set because of an unknown failure.
+     */
+    FAILURE_UNKNOWN = 1,
+
+    /**
+     * The eARC enabled setting could not be set because the arguments were invalid.
+     */
+    FAILURE_INVALID_ARGS = 2,
+
+    /**
+     * The eARC enabled setting could not be set because eARC feature is not supported.
+     */
+    FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/earc/aidl/default/Android.bp b/tv/earc/aidl/default/Android.bp
new file mode 100644
index 0000000..399f029
--- /dev/null
+++ b/tv/earc/aidl/default/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.earc-service",
+    vintf_fragments: ["android.hardware.tv.earc-service.xml"],
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    init_rc: ["android.hardware.tv.earc-service.rc"],
+    srcs: [
+        "serviceMock.cpp",
+        "EArcMock.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+        "libbase",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "android.hardware.tv.earc-V1-ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.tv.earc-service_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.tv.earc-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "EArcMock.cpp",
+    ],
+    fuzz_config: {
+        componentid: 826094,
+    },
+}
diff --git a/tv/earc/aidl/default/EArcMock.cpp b/tv/earc/aidl/default/EArcMock.cpp
new file mode 100644
index 0000000..9bccc18
--- /dev/null
+++ b/tv/earc/aidl/default/EArcMock.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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 "android.hardware.tv.earc"
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+#include "EArcMock.h"
+
+using ndk::ScopedAStatus;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace earc {
+namespace implementation {
+
+void EArcMock::serviceDied(void* cookie) {
+    ALOGE("EArcMock died");
+    auto eArc = static_cast<EArcMock*>(cookie);
+    eArc->mEArcEnabled = false;
+}
+
+ScopedAStatus EArcMock::setEArcEnabled(bool in_enabled) {
+    mEArcEnabled = in_enabled;
+    if (mEArcEnabled != in_enabled) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::FAILURE_UNKNOWN));
+    } else {
+        return ScopedAStatus::ok();
+    }
+}
+
+ScopedAStatus EArcMock::isEArcEnabled(bool* _aidl_return) {
+    *_aidl_return = mEArcEnabled;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getState(int32_t portId, IEArcStatus* _aidl_return) {
+    // Maintain port connection status and update on hotplug event
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mPortStatus[portId];
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getLastReportedAudioCapabilities(int32_t portId,
+                                                         std::vector<uint8_t>* _aidl_return) {
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mCapabilities[portId];
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::setCallback(const std::shared_ptr<IEArcCallback>& callback) {
+    if (mCallback != nullptr) {
+        mCallback = nullptr;
+    }
+
+    if (callback != nullptr) {
+        mCallback = callback;
+        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::reportCapabilities(const std::vector<uint8_t> capabilities,
+                                           int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onCapabilitiesReported(capabilities, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+ScopedAStatus EArcMock::changeState(const IEArcStatus status, int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onStateChange(status, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+EArcMock::EArcMock() {
+    ALOGE("[halimp_aidl] Opening a virtual eARC HAL for testing and virtual machine.");
+    mCallback = nullptr;
+    mCapabilities.resize(mTotalPorts);
+    mPortStatus.resize(mTotalPorts);
+    mPortStatus[0] = IEArcStatus::STATUS_IDLE;
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+}
+
+}  // namespace implementation
+}  // namespace earc
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/earc/aidl/default/EArcMock.h b/tv/earc/aidl/default/EArcMock.h
new file mode 100644
index 0000000..9081950
--- /dev/null
+++ b/tv/earc/aidl/default/EArcMock.h
@@ -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 <aidl/android/hardware/tv/earc/BnEArc.h>
+#include <aidl/android/hardware/tv/earc/Result.h>
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace earc {
+namespace implementation {
+
+using ::aidl::android::hardware::tv::earc::BnEArc;
+using ::aidl::android::hardware::tv::earc::IEArc;
+using ::aidl::android::hardware::tv::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::earc::Result;
+
+struct EArcMock : public BnEArc {
+    EArcMock();
+
+    ::ndk::ScopedAStatus setEArcEnabled(bool in_enabled) override;
+    ::ndk::ScopedAStatus isEArcEnabled(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IEArcCallback>& in_callback) override;
+    ::ndk::ScopedAStatus getState(int32_t in_portId, IEArcStatus* _aidl_return) override;
+    ::ndk::ScopedAStatus getLastReportedAudioCapabilities(
+            int32_t in_portId, std::vector<uint8_t>* _aidl_return) override;
+    ::ndk::ScopedAStatus reportCapabilities(const std::vector<uint8_t> capabilities,
+                                            int32_t portId);
+    ::ndk::ScopedAStatus changeState(const IEArcStatus status, int32_t portId);
+
+  private:
+    static void* __threadLoop(void* data);
+    void threadLoop();
+
+  private:
+    static void serviceDied(void* cookie);
+    std::shared_ptr<IEArcCallback> mCallback;
+
+    // Variables for the virtual EARC hal impl
+    std::vector<std::vector<uint8_t>> mCapabilities;
+    std::vector<IEArcStatus> mPortStatus;
+    bool mEArcEnabled = true;
+
+    // Port configuration
+    int mTotalPorts = 1;
+
+    // Testing variables
+    pthread_t mThreadId = 0;
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+}  // namespace implementation
+}  // namespace earc
+}  // Namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.rc b/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
new file mode 100644
index 0000000..0d9063e
--- /dev/null
+++ b/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
@@ -0,0 +1,5 @@
+service vendor.earc-default /vendor/bin/hw/android.hardware.tv.earc-service
+    interface aidl android.hardware.tv.earc.IEArc/default
+    class hal
+    user system
+    group system
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.xml b/tv/earc/aidl/default/android.hardware.tv.earc-service.xml
new file mode 100644
index 0000000..4d66d98
--- /dev/null
+++ b/tv/earc/aidl/default/android.hardware.tv.earc-service.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/tv/earc/aidl/default/fuzzer.cpp b/tv/earc/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..5036853
--- /dev/null
+++ b/tv/earc/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <EArcMock.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using android::fuzzService;
+using android::hardware::tv::earc::implementation::EArcMock;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto earcAidl = SharedRefBase::make<EArcMock>();
+
+    fuzzService(earcAidl->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/tv/earc/aidl/default/serviceMock.cpp b/tv/earc/aidl/default/serviceMock.cpp
new file mode 100644
index 0000000..1ea7262
--- /dev/null
+++ b/tv/earc/aidl/default/serviceMock.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 "android.hardware.tv.earc-service-shim"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include "EArcMock.h"
+
+using android::hardware::tv::earc::implementation::EArcMock;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<EArcMock> earcAidl = ndk::SharedRefBase::make<EArcMock>();
+    const std::string instance = std::string() + EArcMock::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(earcAidl->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/earc/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..797547e
--- /dev/null
+++ b/tv/earc/aidl/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalTvEArcAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.tv.earc-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp b/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
new file mode 100644
index 0000000..12f48c3
--- /dev/null
+++ b/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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 "EArc_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/earc/BnEArcCallback.h>
+#include <aidl/android/hardware/tv/earc/IEArc.h>
+#include <aidl/android/hardware/tv/earc/IEArcStatus.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sstream>
+#include <vector>
+
+using ::aidl::android::hardware::tv::earc::BnEArcCallback;
+using ::aidl::android::hardware::tv::earc::IEArc;
+using ::aidl::android::hardware::tv::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::earc::IEArcStatus;
+using ::ndk::SpAIBinder;
+
+// The main test class for TV EARC HAL.
+class EArcTest : public ::testing::TestWithParam<std::string> {
+    static void serviceDied(void* /* cookie */) { ALOGE("VtsHalTvCecAidlTargetTest died"); }
+
+  public:
+    void SetUp() override {
+        eArc = IEArc::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(eArc, nullptr);
+        ALOGI("%s: getService() for eArc is %s", __func__, eArc->isRemote() ? "remote" : "local");
+
+        eArcCallback = ::ndk::SharedRefBase::make<EArcCallback>();
+        ASSERT_NE(eArcCallback, nullptr);
+        eArcDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+        ASSERT_EQ(AIBinder_linkToDeath(eArc->asBinder().get(), eArcDeathRecipient.get(), 0),
+                  STATUS_OK);
+    }
+
+    class EArcCallback : public BnEArcCallback {
+      public:
+        ::ndk::ScopedAStatus onStateChange(IEArcStatus connected __unused,
+                                           int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+        ::ndk::ScopedAStatus onCapabilitiesReported(
+                const std::vector<uint8_t>& capabilities __unused, int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+    };
+
+    std::shared_ptr<IEArc> eArc;
+    std::shared_ptr<IEArcCallback> eArcCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient eArcDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EArcTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, EArcTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IEArc::descriptor)),
+                         android::PrintInstanceNameToString);
+
+TEST_P(EArcTest, setGetEArcEnabled) {
+    bool initial_state;
+    bool changed_state;
+    ASSERT_TRUE(eArc->isEArcEnabled(&initial_state).isOk());
+    ASSERT_TRUE(eArc->setEArcEnabled(!initial_state).isOk());
+    ASSERT_TRUE(eArc->isEArcEnabled(&changed_state).isOk());
+    ASSERT_TRUE(initial_state != changed_state);
+    ASSERT_TRUE(eArc->setEArcEnabled(initial_state).isOk());
+}
+
+TEST_P(EArcTest, SetCallback) {
+    ASSERT_TRUE(eArc->setCallback(eArcCallback).isOk());
+}
+
+TEST_P(EArcTest, GetState) {
+    IEArcStatus connectionStatus;
+    ASSERT_TRUE(eArc->getState(1, &connectionStatus).isOk());
+}
+
+TEST_P(EArcTest, GetLastReportedAudioCapabilities) {
+    std::vector<uint8_t> capabilities;
+    ASSERT_TRUE(eArc->getLastReportedAudioCapabilities(1, &capabilities).isOk());
+}
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
new file mode 100644
index 0000000..eef4025
--- /dev/null
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.hdmi;
+@Backing(type="byte") @VintfStability
+enum HpdSignal {
+  HDMI_HPD_PHYSICAL = 0,
+  HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
index 3fc7f41..809d392 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
@@ -37,4 +37,6 @@
   android.hardware.tv.hdmi.HdmiPortInfo[] getPortInfo();
   boolean isConnected(in int portId);
   void setCallback(in android.hardware.tv.hdmi.IHdmiCallback callback);
+  void setHpdSignal(android.hardware.tv.hdmi.HpdSignal signal);
+  android.hardware.tv.hdmi.HpdSignal getHpdSignal();
 }
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
new file mode 100644
index 0000000..b6b0eb3
--- /dev/null
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.hdmi;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_INVALID_STATE = 3,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
new file mode 100644
index 0000000..05963f2
--- /dev/null
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi;
+
+/**
+ * HPD (Hotplug Detection) Signal Types
+ */
+@VintfStability
+@Backing(type="byte")
+enum HpdSignal {
+    HDMI_HPD_PHYSICAL = 0,
+    HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
index 5536846..457234d 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
@@ -17,6 +17,7 @@
 package android.hardware.tv.hdmi;
 
 import android.hardware.tv.hdmi.HdmiPortInfo;
+import android.hardware.tv.hdmi.HpdSignal;
 import android.hardware.tv.hdmi.IHdmiCallback;
 
 /**
@@ -48,4 +49,17 @@
      *        setCallback(null) should deregister the callback.
      */
     void setCallback(in IHdmiCallback callback);
+
+    /**
+     * Method to set the HPD (Hot Plug Detection) signal the HAL should use for HPD signaling (e.g.
+     * signaling EDID updates). By default, the HAL will use {@code HDMI_HPD_PHYSICAL} (the physical
+     * hotplug signal). When set to {@code HDMI_HPD_STATUS_BIT} the HAL should use the HDP status
+     * bit.
+     */
+    void setHpdSignal(HpdSignal signal);
+
+    /**
+     * Get the current signal the HAL is using for HPD
+     */
+    HpdSignal getHpdSignal();
 }
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
new file mode 100644
index 0000000..d2a1fef
--- /dev/null
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi;
+
+/**
+ * Result enum for return values. Used by the HDMI related AIDL.
+ */
+@VintfStability
+enum Result {
+    /**
+     * The HPD Signal type was set successfully.
+     */
+    SUCCESS = 0,
+
+    /**
+     * The HPD Signal type could not be set because of an unknown failure.
+     */
+    FAILURE_UNKNOWN = 1,
+
+    /**
+     * The HPD Signal type could not be set because the arguments were invalid.
+     */
+    FAILURE_INVALID_ARGS = 2,
+
+    /**
+     * The HPD Signal type could not be set because the HAL is in an invalid state.
+     */
+    FAILURE_INVALID_STATE = 3,
+
+    /**
+     * The HPD Signal type could not be set as the signal type is not supported.
+     */
+    FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/aidl/default/HdmiMock.cpp b/tv/hdmi/aidl/default/HdmiMock.cpp
index bbc4705..7cd9bb7 100644
--- a/tv/hdmi/aidl/default/HdmiMock.cpp
+++ b/tv/hdmi/aidl/default/HdmiMock.cpp
@@ -67,6 +67,21 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus HdmiMock::setHpdSignal(HpdSignal signal) {
+    if (mHdmiThreadRun) {
+        mHpdSignal = signal;
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::FAILURE_INVALID_STATE));
+    }
+}
+
+ScopedAStatus HdmiMock::getHpdSignal(HpdSignal* _aidl_return) {
+    *_aidl_return = mHpdSignal;
+    return ScopedAStatus::ok();
+}
+
 void* HdmiMock::__threadLoop(void* user) {
     HdmiMock* const self = static_cast<HdmiMock*>(user);
     self->threadLoop();
diff --git a/tv/hdmi/aidl/default/HdmiMock.h b/tv/hdmi/aidl/default/HdmiMock.h
index 05795dd..51abaff 100644
--- a/tv/hdmi/aidl/default/HdmiMock.h
+++ b/tv/hdmi/aidl/default/HdmiMock.h
@@ -15,6 +15,7 @@
  */
 
 #include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
+#include <aidl/android/hardware/tv/hdmi/Result.h>
 #include <algorithm>
 #include <vector>
 
@@ -29,8 +30,10 @@
 using ::aidl::android::hardware::tv::hdmi::BnHdmi;
 using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
 using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::HpdSignal;
 using ::aidl::android::hardware::tv::hdmi::IHdmi;
 using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
+using ::aidl::android::hardware::tv::hdmi::Result;
 
 #define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
 #define MESSAGE_BODY_MAX_LENGTH 4
@@ -41,6 +44,8 @@
     ::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
     ::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
     ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCallback>& callback) override;
+    ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal) override;
+    ::ndk::ScopedAStatus getHpdSignal(HpdSignal* _aidl_return) override;
 
     void printEventBuf(const char* msg_buf, int len);
 
@@ -62,6 +67,9 @@
     uint16_t mPhysicalAddress = 0xFFFF;
     int mTotalPorts = 1;
 
+    // HPD Signal being used
+    HpdSignal mHpdSignal = HpdSignal::HDMI_HPD_PHYSICAL;
+
     // Testing variables
     // Input file descriptor
     int mInputFile;
diff --git a/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp b/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
index 78c2590..fd4d94f 100644
--- a/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
+++ b/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
@@ -31,6 +31,7 @@
 using ::aidl::android::hardware::tv::hdmi::BnHdmiCallback;
 using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
 using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::HpdSignal;
 using ::aidl::android::hardware::tv::hdmi::IHdmi;
 using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
 using ::ndk::SpAIBinder;
@@ -101,3 +102,18 @@
         ASSERT_TRUE(hdmi->isConnected(ports[i].portId, &connected).isOk());
     }
 }
+
+TEST_P(HdmiTest, HdpSignal) {
+    HpdSignal originalSignal;
+    HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
+    HpdSignal readSignal;
+    ASSERT_TRUE(hdmi->getHpdSignal(&originalSignal).isOk());
+    ASSERT_TRUE(hdmi->setHpdSignal(signal).isOk());
+    ASSERT_TRUE(hdmi->getHpdSignal(&readSignal).isOk());
+    EXPECT_EQ(readSignal, signal);
+    signal = HpdSignal::HDMI_HPD_PHYSICAL;
+    ASSERT_TRUE(hdmi->setHpdSignal(signal).isOk());
+    ASSERT_TRUE(hdmi->getHpdSignal(&readSignal).isOk());
+    EXPECT_EQ(readSignal, signal);
+    ASSERT_TRUE(hdmi->setHpdSignal(originalSignal).isOk());
+}
diff --git a/usb/1.0/default/OWNERS b/usb/1.0/default/OWNERS
deleted file mode 100644
index fefae56..0000000
--- a/usb/1.0/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-badhri@google.com
diff --git a/usb/1.0/vts/OWNERS b/usb/1.0/vts/OWNERS
deleted file mode 100644
index 54f268f..0000000
--- a/usb/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-badhri@google.com
-yim@google.com
-trong@google.com
diff --git a/usb/1.1/vts/OWNERS b/usb/1.1/vts/OWNERS
deleted file mode 100644
index 54f268f..0000000
--- a/usb/1.1/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-badhri@google.com
-yim@google.com
-trong@google.com
diff --git a/usb/1.2/vts/OWNERS b/usb/1.2/vts/OWNERS
deleted file mode 100644
index f60d39a..0000000
--- a/usb/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-badhri@google.com
-yim@google.com
diff --git a/usb/1.3/vts/OWNERS b/usb/OWNERS
similarity index 62%
rename from usb/1.3/vts/OWNERS
rename to usb/OWNERS
index a6a1e54..2b1d34d 100644
--- a/usb/1.3/vts/OWNERS
+++ b/usb/OWNERS
@@ -1,2 +1,4 @@
+# Bug component: 175220
+
 albertccwang@google.com
 badhri@google.com
diff --git a/usb/aidl/OWNERS b/usb/aidl/OWNERS
deleted file mode 100644
index fefae56..0000000
--- a/usb/aidl/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-badhri@google.com
diff --git a/vibrator/1.0/vts/OWNERS b/vibrator/1.0/vts/OWNERS
deleted file mode 100644
index 75b9a4b..0000000
--- a/vibrator/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 345036
-michaelwr@google.com
-leungv@google.com
diff --git a/vibrator/1.1/vts/OWNERS b/vibrator/1.1/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/1.2/vts/OWNERS b/vibrator/1.2/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/1.3/example/OWNERS b/vibrator/1.3/example/OWNERS
deleted file mode 100644
index 4b34968..0000000
--- a/vibrator/1.3/example/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-eliptus@google.com
-michaelwr@google.com
diff --git a/vibrator/1.3/vts/OWNERS b/vibrator/1.3/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.3/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/aidl/OWNERS b/vibrator/OWNERS
similarity index 68%
rename from vibrator/aidl/OWNERS
rename to vibrator/OWNERS
index 3982c7b..05e2e73 100644
--- a/vibrator/aidl/OWNERS
+++ b/vibrator/OWNERS
@@ -1,4 +1,9 @@
 # Bug component: 345036
+
 include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
+
 chasewu@google.com
+chrispaulo@google.com
+michaelwr@google.com
+nathankulczak@google.com
 taikuo@google.com