Merge "Remove length check to allow empty HDR10+ blobs to HWC"
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index e69306e..56ac510 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -109,7 +109,6 @@
         "android.hardware.audio_defaults",
     ],
     srcs: [
-        "android/hardware/audio/core/AudioMode.aidl",
         "android/hardware/audio/core/AudioPatch.aidl",
         "android/hardware/audio/core/AudioRoute.aidl",
         "android/hardware/audio/core/IBluetooth.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
index 289c0c2..9357a15 100644
--- 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
@@ -44,10 +44,10 @@
     @nullable @utf8InCpp String debugName;
     @VintfStability
     enum Mode {
-      UNSPECIFIED = 0,
-      SCO = 1,
-      SCO_WB = 2,
-      SCO_SWB = 3,
+      UNSPECIFIED,
+      SCO,
+      SCO_WB,
+      SCO_SWB,
     }
   }
   @JavaDerive(equals=true, toString=true) @VintfStability
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 4486b66..960e69f 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
@@ -59,7 +59,7 @@
   boolean getMicMute();
   void setMicMute(boolean mute);
   android.hardware.audio.core.MicrophoneInfo[] getMicrophones();
-  void updateAudioMode(android.hardware.audio.core.AudioMode mode);
+  void updateAudioMode(android.media.audio.common.AudioMode mode);
   void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
   void updateScreenState(boolean isTurnedOn);
   @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
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 77063df..001d074 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
@@ -34,8 +34,8 @@
 package android.hardware.audio.core;
 @VintfStability
 interface ITelephony {
-  android.hardware.audio.core.AudioMode[] getSupportedAudioModes();
-  void switchAudioMode(android.hardware.audio.core.AudioMode mode);
+  android.media.audio.common.AudioMode[] getSupportedAudioModes();
+  void switchAudioMode(android.media.audio.common.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 {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 7f34f33..9edad09 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -44,22 +44,6 @@
   int diffusionPm;
   int densityPm;
   boolean bypass;
-  const int MIN_ROOM_LEVEL_MB = (-6000);
-  const int MAX_ROOM_LEVEL_MB = 0;
-  const int MIN_ROOM_HF_LEVEL_MB = (-4000);
-  const int MAX_ROOM_HF_LEVEL_MB = 0;
-  const int MIN_DECAY_TIME_MS = 100;
-  const int MAX_DECAY_TIME_MS = 20000;
-  const int MIN_DECAY_HF_RATIO_PM = 100;
-  const int MAX_DECAY_HF_RATIO_PM = 1000;
-  const int MIN_LEVEL_MB = (-6000);
-  const int MAX_LEVEL_MB = 0;
-  const int MIN_DELAY_MS = 0;
-  const int MAX_DELAY_MS = 65;
-  const int MIN_DIFFUSION_PM = 0;
-  const int MAX_DIFFUSION_PM = 1000;
-  const int MIN_DENSITY_PM = 0;
-  const int MAX_DENSITY_PM = 1000;
   @VintfStability
   union Id {
     int vendorExtensionTag;
@@ -68,6 +52,17 @@
   @VintfStability
   parcelable Capability {
     android.hardware.audio.effect.VendorExtension extension;
+    int minRoomLevelMb;
+    int maxRoomLevelMb;
+    int minRoomHfLevelMb;
+    int maxRoomHfLevelMb;
     int maxDecayTimeMs;
+    int minDecayHfRatioPm;
+    int maxDecayHfRatioPm;
+    int minLevelMb;
+    int maxLevelMb;
+    int maxDelayMs;
+    int maxDiffusionPm;
+    int maxDensityPm;
   }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index eaa4bb1..3ba44a0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 union Parameter {
   android.hardware.audio.effect.Parameter.Common common;
-  android.media.audio.common.AudioDeviceDescription deviceDescription;
+  android.media.audio.common.AudioDeviceDescription[] deviceDescription;
   android.media.audio.common.AudioMode mode;
   android.media.audio.common.AudioSource source;
   android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
diff --git a/audio/aidl/android/hardware/audio/core/AudioMode.aidl b/audio/aidl/android/hardware/audio/core/AudioMode.aidl
deleted file mode 100644
index 0943a55..0000000
--- a/audio/aidl/android/hardware/audio/core/AudioMode.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.audio.core;
-
-/**
- * The audio mode describes states of the audio system of the device that
- * can significantly affect the rules of audio routing, volume control, etc.
- * The audio mode is controlled by the framework, however the HAL has some
- * flexibility in the choice of modes to support, see 'IModule.updateAudioMode'.
- */
-@VintfStability
-@Backing(type="int")
-enum AudioMode {
-    /** No active calls. */
-    NORMAL = 0,
-    /** The device is playing the ringtone. */
-    RINGTONE = 1,
-    /** The call is handled by the telephony stack ("voice call"). */
-    IN_CALL = 2,
-    /** The call is handled by an application ("VoIP call"). */
-    IN_COMMUNICATION = 3,
-    /** Call screening is in progress. */
-    CALL_SCREEN = 4,
-}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 7bc1b9c..2c478f2 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -18,7 +18,6 @@
 
 import android.hardware.audio.common.SinkMetadata;
 import android.hardware.audio.common.SourceMetadata;
-import android.hardware.audio.core.AudioMode;
 import android.hardware.audio.core.AudioPatch;
 import android.hardware.audio.core.AudioRoute;
 import android.hardware.audio.core.IBluetooth;
@@ -33,6 +32,7 @@
 import android.hardware.audio.core.VendorParameter;
 import android.hardware.audio.core.sounddose.ISoundDose;
 import android.hardware.audio.effect.IEffect;
+import android.media.audio.common.AudioMode;
 import android.media.audio.common.AudioOffloadInfo;
 import android.media.audio.common.AudioPort;
 import android.media.audio.common.AudioPortConfig;
@@ -684,6 +684,7 @@
      * method.
      *
      * @param mode The current mode.
+     * @throws EX_ILLEGAL_ARGUMENT If the mode is out of range of valid values.
      */
     void updateAudioMode(AudioMode mode);
 
diff --git a/audio/aidl/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
index a817032..7fc1ace 100644
--- a/audio/aidl/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.audio.core;
 
-import android.hardware.audio.core.AudioMode;
+import android.media.audio.common.AudioMode;
 import android.media.audio.common.Boolean;
 import android.media.audio.common.Float;
 
@@ -52,6 +52,7 @@
      *
      * @param mode The mode to switch to.
      * @throws EX_UNSUPPORTED_OPERATION If the HAL does not support the specified mode.
+     * @throws EX_ILLEGAL_ARGUMENT If the mode is out of range of valid values.
      * @throws EX_ILLEGAL_STATE If there was an error during switching.
      */
     void switchAudioMode(AudioMode mode);
diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 81c0dde..fc98fe6 100644
--- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -50,112 +50,96 @@
         VendorExtension extension;
 
         /**
+         * Minimal possible room level in millibels.
+         */
+        int minRoomLevelMb;
+        /**
+         * Maximum possible room level in millibels.
+         */
+        int maxRoomLevelMb;
+        /**
+         * Minimal possible room hf level in millibels.
+         */
+        int minRoomHfLevelMb;
+        /**
+         * Maximum possible room hf level in millibels.
+         */
+        int maxRoomHfLevelMb;
+        /**
          * Max decay time supported in millisecond.
          */
         int maxDecayTimeMs;
+        /**
+         * Minimal possible per mille decay hf ratio.
+         */
+        int minDecayHfRatioPm;
+        /**
+         * Maximum possible per mille decay hf ratio.
+         */
+        int maxDecayHfRatioPm;
+        /**
+         * Minimal possible room level in millibels.
+         */
+        int minLevelMb;
+        /**
+         * Maximum possible room level in millibels.
+         */
+        int maxLevelMb;
+        /**
+         * Maximum possible delay time in milliseconds.
+         */
+        int maxDelayMs;
+        /**
+         * Maximum possible per mille diffusion.
+         */
+        int maxDiffusionPm;
+        /**
+         * Maximum possible per mille density.
+         */
+        int maxDensityPm;
     }
 
     /**
-     * Minimal possible room level in millibels.
-     */
-    const int MIN_ROOM_LEVEL_MB = -6000;
-    /**
-     * Maximum possible room level in millibels.
-     */
-    const int MAX_ROOM_LEVEL_MB = 0;
-    /**
-     * Room level apply to the reverb effect in millibels.
+     * Room level apply to the reverb effect in millibels. The value of the roomLevelMb must be in
+     * range of the value specified by the 'minRoomLevelMb' capability and the 'maxRoomLevelMb'
+     * capability.
      */
     int roomLevelMb;
-
     /**
-     * Minimal possible room hf level in millibels.
-     */
-    const int MIN_ROOM_HF_LEVEL_MB = -4000;
-    /**
-     * Maximum possible room hf level in millibels.
-     */
-    const int MAX_ROOM_HF_LEVEL_MB = 0;
-    /**
-     * Room HF level apply to the reverb effect in millibels.
+     * Room HF level apply to the reverb effect in millibels. The value of the roomHfLevelMb must be
+     * in range of the value specified by the 'minRoomHfLevelMb' capability and the
+     * 'maxRoomHfLevelMb' capability.
      */
     int roomHfLevelMb;
-
     /**
-     * Minimal possible decay time in milliseconds.
-     */
-    const int MIN_DECAY_TIME_MS = 100;
-    /**
-     * Maximum possible decay time in milliseconds.
-     */
-    const int MAX_DECAY_TIME_MS = 20000;
-    /**
-     * Delay time apply to the reverb effect in milliseconds.
+     * Delay time apply to the reverb effect in milliseconds.The value of the decayTimeMs must
+     * be non-negative and not exceed the value specified by the 'maxDecayTimeMs' capability.
      */
     int decayTimeMs;
-
     /**
-     * Minimal possible per mille decay hf ratio.
-     */
-    const int MIN_DECAY_HF_RATIO_PM = 100;
-    /**
-     * Maximum possible per mille decay hf ratio.
-     */
-    const int MAX_DECAY_HF_RATIO_PM = 1000;
-    /**
-     * HF decay ratio in permilles.
+     * HF decay ratio in permilles. The value of the decayHfRatioPm must be in range
+     * of the value specified by the 'minDecayHfRatioPm' capability and the 'maxDecayHfRatioPm'
+     * capability.
      */
     int decayHfRatioPm;
-
     /**
-     * Minimal possible room level in millibels.
-     */
-    const int MIN_LEVEL_MB = -6000;
-    /**
-     * Maximum possible room level in millibels.
-     */
-    const int MAX_LEVEL_MB = 0;
-    /**
-     * Reverb level in millibels.
+     * Reverb level in millibels. The value of the levelMb must be in range
+     * of the value specified by the 'minLevelMb' capability and the 'maxLevelMb' capability.
      */
     int levelMb;
-
     /**
-     * Minimal possible delay time in milliseconds.
-     */
-    const int MIN_DELAY_MS = 0;
-    /**
-     * Maximum possible delay time in milliseconds.
-     */
-    const int MAX_DELAY_MS = 65;
-    /**
-     * Reverb delay in milliseconds.
+     * Reverb delay in milliseconds. The value of the delayMs must be non-negative and not
+     * exceed the value specified by the 'maxDelayMs' capability.
      */
     int delayMs;
-
     /**
-     * Minimal possible per mille diffusion.
-     */
-    const int MIN_DIFFUSION_PM = 0;
-    /**
-     * Maximum possible per mille diffusion.
-     */
-    const int MAX_DIFFUSION_PM = 1000;
-    /**
-     * Diffusion in permilles.
+     * Diffusion in permilles. The value of the diffusionPm must be non-negative and not
+     * exceed the value specified by the 'maxDiffusionPm' capability.
      */
     int diffusionPm;
-
     /**
-     * Minimal possible per mille density.
-     */
-    const int MIN_DENSITY_PM = 0;
-    /**
-     * Maximum possible per mille density.
-     */
-    const int MAX_DENSITY_PM = 1000;
-    /**
-     * Density in permilles.
+     * Density in permilles. The value of the densityPm must be non-negative and not
+     * exceed the value specified by the 'maxDensityPm' capability.
      */
     int densityPm;
 
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 1c001d2..473dfb5 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -120,10 +120,11 @@
     Common common;
 
     /**
-     * Used by audio framework to set the device type to effect engine.
-     * Effect must implement setParameter(device) if Flags.deviceIndication set to true.
+     * Used by audio framework to set the device type(s) to effect engine.
+     * Effect engine must apply all AudioDeviceDescription in the list.
+     * Effect must implement setParameter(deviceDescription) if Flags.deviceIndication set to true.
      */
-    AudioDeviceDescription deviceDescription;
+    AudioDeviceDescription[] deviceDescription;
     /**
      * Used by audio framework to set the audio mode to effect engine.
      * Effect must implement setParameter(mode) if Flags.audioModeIndication set to true.
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 8f0c986..2aaa781 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <algorithm>
+#include <array>
 #include <initializer_list>
 #include <type_traits>
 
@@ -23,11 +25,22 @@
 #include <aidl/android/media/audio/common/AudioDeviceType.h>
 #include <aidl/android/media/audio/common/AudioFormatDescription.h>
 #include <aidl/android/media/audio/common/AudioInputFlags.h>
+#include <aidl/android/media/audio/common/AudioMode.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 #include <aidl/android/media/audio/common/PcmType.h>
 
 namespace android::hardware::audio::common {
 
+// Some values are reserved for use by the system code only.
+// HALs must not accept or emit values outside from the provided list.
+constexpr std::array<::aidl::android::media::audio::common::AudioMode, 5> kValidAudioModes = {
+        ::aidl::android::media::audio::common::AudioMode::NORMAL,
+        ::aidl::android::media::audio::common::AudioMode::RINGTONE,
+        ::aidl::android::media::audio::common::AudioMode::IN_CALL,
+        ::aidl::android::media::audio::common::AudioMode::IN_COMMUNICATION,
+        ::aidl::android::media::audio::common::AudioMode::CALL_SCREEN,
+};
+
 constexpr size_t getPcmSampleSizeInBytes(::aidl::android::media::audio::common::PcmType pcm) {
     using ::aidl::android::media::audio::common::PcmType;
     switch (pcm) {
@@ -91,6 +104,11 @@
            device == ::aidl::android::media::audio::common::AudioDeviceType::OUT_TELEPHONY_TX;
 }
 
+constexpr bool isValidAudioMode(::aidl::android::media::audio::common::AudioMode mode) {
+    return std::find(kValidAudioModes.begin(), kValidAudioModes.end(), mode) !=
+           kValidAudioModes.end();
+}
+
 // The helper functions defined below are only applicable to the case when an enum type
 // specifies zero-based bit positions, not bit masks themselves. This is why instantiation
 // is restricted to certain enum types.
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 1e6785f..95043f7 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -69,6 +69,7 @@
         "Module.cpp",
         "SoundDose.cpp",
         "Stream.cpp",
+        "StreamStub.cpp",
         "Telephony.cpp",
     ],
     generated_sources: [
@@ -163,6 +164,7 @@
         "libloudnessenhanceraidl",
         "libnssw",
         "libpresetreverbsw",
+        "libreverbaidl",
         "libtinyxml2",
         "libvirtualizersw",
         "libvisualizeraidl",
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 3b40ae0..5cd87fd 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -165,7 +165,7 @@
     return status;
 }
 
-void Factory::openEffectLibrary(const AudioUuid& impl, const std::string& libName) {
+bool Factory::openEffectLibrary(const AudioUuid& impl, const std::string& libName) {
     std::function<void(void*)> dlClose = [](void* handle) -> void {
         if (handle && dlclose(handle)) {
             LOG(ERROR) << "dlclose failed " << dlerror();
@@ -176,7 +176,7 @@
             std::unique_ptr<void, decltype(dlClose)>{dlopen(libName.c_str(), RTLD_LAZY), dlClose};
     if (!libHandle) {
         LOG(ERROR) << __func__ << ": dlopen failed, err: " << dlerror();
-        return;
+        return false;
     }
 
     LOG(INFO) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
@@ -186,6 +186,7 @@
             {impl,
              std::make_tuple(std::move(libHandle),
                              std::unique_ptr<struct effect_dl_interface_s>(interface), libName)});
+    return true;
 }
 
 void Factory::createIdentityWithConfig(const EffectConfig::LibraryUuid& configLib,
@@ -201,8 +202,9 @@
         LOG(DEBUG) << __func__ << ": typeUuid " << id.type.toString() << "\nimplUuid "
                    << id.uuid.toString() << " proxyUuid "
                    << (proxyUuid.has_value() ? proxyUuid->toString() : "null");
-        openEffectLibrary(id.uuid, path->second);
-        mIdentitySet.insert(std::move(id));
+        if (openEffectLibrary(id.uuid, path->second)) {
+            mIdentitySet.insert(std::move(id));
+        }
     } else {
         LOG(ERROR) << __func__ << ": library " << libName << " not exist!";
         return;
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 13b04cd..a6e1d0d 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -28,6 +28,7 @@
 #include "core-impl/Bluetooth.h"
 #include "core-impl/Module.h"
 #include "core-impl/SoundDose.h"
+#include "core-impl/StreamStub.h"
 #include "core-impl/Telephony.h"
 #include "core-impl/utils.h"
 
@@ -40,6 +41,7 @@
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioInputFlags;
 using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioMode;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPort;
@@ -51,6 +53,7 @@
 using aidl::android::media::audio::common::PcmType;
 using android::hardware::audio::common::getFrameSizeInBytes;
 using android::hardware::audio::common::isBitPositionFlagSet;
+using android::hardware::audio::common::isValidAudioMode;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -102,9 +105,10 @@
     erase_all_values(mPatches, std::set<int32_t>{patchId});
 }
 
-ndk::ScopedAStatus Module::createStreamContext(int32_t in_portConfigId, int64_t in_bufferSizeFrames,
-                                               std::shared_ptr<IStreamCallback> asyncCallback,
-                                               StreamContext* out_context) {
+ndk::ScopedAStatus Module::createStreamContext(
+        int32_t in_portConfigId, int64_t in_bufferSizeFrames,
+        std::shared_ptr<IStreamCallback> asyncCallback,
+        std::shared_ptr<IStreamOutEventCallback> outEventCallback, StreamContext* out_context) {
     if (in_bufferSizeFrames <= 0) {
         LOG(ERROR) << __func__ << ": non-positive buffer size " << in_bufferSizeFrames;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -147,7 +151,7 @@
                 std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
                 portConfigIt->format.value(), portConfigIt->channelMask.value(),
                 std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
-                asyncCallback, params);
+                asyncCallback, outEventCallback, params);
         if (temp.isValid()) {
             *out_context = std::move(temp);
         } else {
@@ -545,14 +549,15 @@
     }
     StreamContext context;
     if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr,
-                                          &context);
+                                          nullptr, &context);
         !status.isOk()) {
         return status;
     }
     context.fillDescriptor(&_aidl_return->desc);
     std::shared_ptr<StreamIn> stream;
-    if (auto status = StreamIn::createInstance(in_args.sinkMetadata, std::move(context),
-                                               mConfig->microphones, &stream);
+    // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
+    if (auto status = StreamInStub::createInstance(in_args.sinkMetadata, std::move(context),
+                                                   mConfig->microphones, &stream);
         !status.isOk()) {
         return status;
     }
@@ -598,14 +603,16 @@
     }
     StreamContext context;
     if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames,
-                                          isNonBlocking ? in_args.callback : nullptr, &context);
+                                          isNonBlocking ? in_args.callback : nullptr,
+                                          in_args.eventCallback, &context);
         !status.isOk()) {
         return status;
     }
     context.fillDescriptor(&_aidl_return->desc);
     std::shared_ptr<StreamOut> stream;
-    if (auto status = StreamOut::createInstance(in_args.sourceMetadata, std::move(context),
-                                                in_args.offloadInfo, &stream);
+    // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
+    if (auto status = StreamOutStub::createInstance(in_args.sourceMetadata, std::move(context),
+                                                    in_args.offloadInfo, &stream);
         !status.isOk()) {
         return status;
     }
@@ -947,6 +954,10 @@
 }
 
 ndk::ScopedAStatus Module::updateAudioMode(AudioMode in_mode) {
+    if (!isValidAudioMode(in_mode)) {
+        LOG(ERROR) << __func__ << ": invalid mode " << toString(in_mode);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
     // No checks for supported audio modes here, it's an informative notification.
     LOG(DEBUG) << __func__ << ": " << toString(in_mode);
     return ndk::ScopedAStatus::ok();
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 0520cba..25814e4 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -85,16 +85,19 @@
     if (mCommandMQ == nullptr) return "Command MQ is null";
     if (mReplyMQ == nullptr) return "Reply MQ is null";
     if (mDataMQ == nullptr) return "Data MQ is null";
-    if (sizeof(decltype(mDataBuffer)::element_type) != mDataMQ->getQuantumSize()) {
+    if (sizeof(DataBufferElement) != mDataMQ->getQuantumSize()) {
         return "Unexpected Data MQ quantum size: " + std::to_string(mDataMQ->getQuantumSize());
     }
     mDataBufferSize = mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize();
-    mDataBuffer.reset(new (std::nothrow) int8_t[mDataBufferSize]);
+    mDataBuffer.reset(new (std::nothrow) DataBufferElement[mDataBufferSize]);
     if (mDataBuffer == nullptr) {
         return "Failed to allocate data buffer for element count " +
                std::to_string(mDataMQ->getQuantumCount()) +
                ", size in bytes: " + std::to_string(mDataBufferSize);
     }
+    if (::android::status_t status = mDriver->init(); status != STATUS_OK) {
+        return "Failed to initialize the driver: " + std::to_string(status);
+    }
     return "";
 }
 
@@ -191,46 +194,59 @@
             }
             break;
         case Tag::drain:
-            if (command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED) {
+            if (const auto mode = command.get<Tag::drain>();
+                mode == StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED) {
                 if (mState == StreamDescriptor::State::ACTIVE) {
-                    usleep(1000);  // Simulate a blocking call into the driver.
-                    populateReply(&reply, mIsConnected);
-                    // Can switch the state to ERROR if a driver error occurs.
-                    mState = StreamDescriptor::State::DRAINING;
+                    if (::android::status_t status = mDriver->drain(mode);
+                        status == ::android::OK) {
+                        populateReply(&reply, mIsConnected);
+                        mState = StreamDescriptor::State::DRAINING;
+                    } else {
+                        LOG(ERROR) << __func__ << ": drain failed: " << status;
+                        mState = StreamDescriptor::State::ERROR;
+                    }
                 } else {
                     populateReplyWrongState(&reply, command);
                 }
             } else {
-                LOG(WARNING) << __func__
-                             << ": invalid drain mode: " << toString(command.get<Tag::drain>());
+                LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
             }
             break;
         case Tag::standby:
             if (mState == StreamDescriptor::State::IDLE) {
-                usleep(1000);  // Simulate a blocking call into the driver.
-                populateReply(&reply, mIsConnected);
-                // Can switch the state to ERROR if a driver error occurs.
-                mState = StreamDescriptor::State::STANDBY;
+                if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": standby failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             } else {
                 populateReplyWrongState(&reply, command);
             }
             break;
         case Tag::pause:
             if (mState == StreamDescriptor::State::ACTIVE) {
-                usleep(1000);  // Simulate a blocking call into the driver.
-                populateReply(&reply, mIsConnected);
-                // Can switch the state to ERROR if a driver error occurs.
-                mState = StreamDescriptor::State::PAUSED;
+                if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::PAUSED;
+                } else {
+                    LOG(ERROR) << __func__ << ": pause failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             } else {
                 populateReplyWrongState(&reply, command);
             }
             break;
         case Tag::flush:
             if (mState == StreamDescriptor::State::PAUSED) {
-                usleep(1000);  // Simulate a blocking call into the driver.
-                populateReply(&reply, mIsConnected);
-                // Can switch the state to ERROR if a driver error occurs.
-                mState = StreamDescriptor::State::STANDBY;
+                if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": flush failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             } else {
                 populateReplyWrongState(&reply, command);
             }
@@ -247,33 +263,39 @@
 }
 
 bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
-    // Can switch the state to ERROR if a driver error occurs.
     const size_t byteCount = std::min({clientSize, mDataMQ->availableToWrite(), mDataBufferSize});
     const bool isConnected = mIsConnected;
+    size_t actualFrameCount = 0;
     bool fatal = false;
-    // Simulate reading of data, or provide zeroes if the stream is not connected.
-    for (size_t i = 0; i < byteCount; ++i) {
-        using buffer_type = decltype(mDataBuffer)::element_type;
-        constexpr int kBufferValueRange = std::numeric_limits<buffer_type>::max() -
-                                          std::numeric_limits<buffer_type>::min() + 1;
-        mDataBuffer[i] = isConnected ? (std::rand() % kBufferValueRange) +
-                                               std::numeric_limits<buffer_type>::min()
-                                     : 0;
+    int32_t latency = Module::kLatencyMs;
+    if (isConnected) {
+        if (::android::status_t status = mDriver->transfer(
+                    mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+            status != ::android::OK) {
+            fatal = true;
+            LOG(ERROR) << __func__ << ": read failed: " << status;
+        }
+    } else {
+        usleep(3000);  // Simulate blocking transfer delay.
+        for (size_t i = 0; i < byteCount; ++i) mDataBuffer[i] = 0;
+        actualFrameCount = byteCount / mFrameSize;
     }
-    usleep(3000);  // Simulate a blocking call into the driver.
-    // Set 'fatal = true' if a driver error occurs.
-    if (bool success = byteCount > 0 ? mDataMQ->write(&mDataBuffer[0], byteCount) : true; success) {
-        LOG(DEBUG) << __func__ << ": writing of " << byteCount << " bytes into data MQ"
+    const size_t actualByteCount = actualFrameCount * mFrameSize;
+    if (bool success =
+                actualByteCount > 0 ? mDataMQ->write(&mDataBuffer[0], actualByteCount) : true;
+        success) {
+        LOG(DEBUG) << __func__ << ": writing of " << actualByteCount << " bytes into data MQ"
                    << " succeeded; connected? " << isConnected;
         // Frames are provided and counted regardless of connection status.
-        reply->fmqByteCount += byteCount;
-        mFrameCount += byteCount / mFrameSize;
+        reply->fmqByteCount += actualByteCount;
+        mFrameCount += actualFrameCount;
         populateReply(reply, isConnected);
     } else {
-        LOG(WARNING) << __func__ << ": writing of " << byteCount << " bytes of data to MQ failed";
+        LOG(WARNING) << __func__ << ": writing of " << actualByteCount
+                     << " bytes of data to MQ failed";
         reply->status = STATUS_NOT_ENOUGH_DATA;
     }
-    reply->latencyMs = Module::kLatencyMs;
+    reply->latencyMs = latency;
     return !fatal;
 }
 
@@ -395,17 +417,22 @@
             }
             break;
         case Tag::drain:
-            if (command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_ALL ||
-                command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY) {
+            if (const auto mode = command.get<Tag::drain>();
+                mode == StreamDescriptor::DrainMode::DRAIN_ALL ||
+                mode == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY) {
                 if (mState == StreamDescriptor::State::ACTIVE ||
                     mState == StreamDescriptor::State::TRANSFERRING) {
-                    usleep(1000);  // Simulate a blocking call into the driver.
-                    populateReply(&reply, mIsConnected);
-                    // Can switch the state to ERROR if a driver error occurs.
-                    if (mState == StreamDescriptor::State::ACTIVE && mForceSynchronousDrain) {
-                        mState = StreamDescriptor::State::IDLE;
+                    if (::android::status_t status = mDriver->drain(mode);
+                        status == ::android::OK) {
+                        populateReply(&reply, mIsConnected);
+                        if (mState == StreamDescriptor::State::ACTIVE && mForceSynchronousDrain) {
+                            mState = StreamDescriptor::State::IDLE;
+                        } else {
+                            switchToTransientState(StreamDescriptor::State::DRAINING);
+                        }
                     } else {
-                        switchToTransientState(StreamDescriptor::State::DRAINING);
+                        LOG(ERROR) << __func__ << ": drain failed: " << status;
+                        mState = StreamDescriptor::State::ERROR;
                     }
                 } else if (mState == StreamDescriptor::State::TRANSFER_PAUSED) {
                     mState = StreamDescriptor::State::DRAIN_PAUSED;
@@ -414,46 +441,58 @@
                     populateReplyWrongState(&reply, command);
                 }
             } else {
-                LOG(WARNING) << __func__
-                             << ": invalid drain mode: " << toString(command.get<Tag::drain>());
+                LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
             }
             break;
         case Tag::standby:
             if (mState == StreamDescriptor::State::IDLE) {
-                usleep(1000);  // Simulate a blocking call into the driver.
-                populateReply(&reply, mIsConnected);
-                // Can switch the state to ERROR if a driver error occurs.
-                mState = StreamDescriptor::State::STANDBY;
+                if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": standby failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             } else {
                 populateReplyWrongState(&reply, command);
             }
             break;
         case Tag::pause: {
-            bool commandAccepted = true;
+            std::optional<StreamDescriptor::State> nextState;
             switch (mState) {
                 case StreamDescriptor::State::ACTIVE:
-                    mState = StreamDescriptor::State::PAUSED;
+                    nextState = StreamDescriptor::State::PAUSED;
                     break;
                 case StreamDescriptor::State::DRAINING:
-                    mState = StreamDescriptor::State::DRAIN_PAUSED;
+                    nextState = StreamDescriptor::State::DRAIN_PAUSED;
                     break;
                 case StreamDescriptor::State::TRANSFERRING:
-                    mState = StreamDescriptor::State::TRANSFER_PAUSED;
+                    nextState = StreamDescriptor::State::TRANSFER_PAUSED;
                     break;
                 default:
                     populateReplyWrongState(&reply, command);
-                    commandAccepted = false;
             }
-            if (commandAccepted) {
-                populateReply(&reply, mIsConnected);
+            if (nextState.has_value()) {
+                if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = nextState.value();
+                } else {
+                    LOG(ERROR) << __func__ << ": pause failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             }
         } break;
         case Tag::flush:
             if (mState == StreamDescriptor::State::PAUSED ||
                 mState == StreamDescriptor::State::DRAIN_PAUSED ||
                 mState == StreamDescriptor::State::TRANSFER_PAUSED) {
-                populateReply(&reply, mIsConnected);
-                mState = StreamDescriptor::State::IDLE;
+                if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::IDLE;
+                } else {
+                    LOG(ERROR) << __func__ << ": flush failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
             } else {
                 populateReplyWrongState(&reply, command);
             }
@@ -472,6 +511,7 @@
 bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
     const size_t readByteCount = mDataMQ->availableToRead();
     bool fatal = false;
+    int32_t latency = Module::kLatencyMs;
     if (bool success = readByteCount > 0 ? mDataMQ->read(&mDataBuffer[0], readByteCount) : true) {
         const bool isConnected = mIsConnected;
         LOG(DEBUG) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
@@ -483,23 +523,36 @@
             // simulate partial write.
             byteCount -= mFrameSize;
         }
+        size_t actualFrameCount = 0;
+        if (isConnected) {
+            if (::android::status_t status = mDriver->transfer(
+                        mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+                status != ::android::OK) {
+                fatal = true;
+                LOG(ERROR) << __func__ << ": write failed: " << status;
+            }
+        } else {
+            if (mAsyncCallback == nullptr) {
+                usleep(3000);  // Simulate blocking transfer delay.
+            }
+            actualFrameCount = byteCount / mFrameSize;
+        }
+        const size_t actualByteCount = actualFrameCount * mFrameSize;
         // Frames are consumed and counted regardless of the connection status.
-        reply->fmqByteCount += byteCount;
-        mFrameCount += byteCount / mFrameSize;
+        reply->fmqByteCount += actualByteCount;
+        mFrameCount += actualFrameCount;
         populateReply(reply, isConnected);
-        usleep(3000);  // Simulate a blocking call into the driver.
-        // Set 'fatal = true' if a driver error occurs.
     } else {
         LOG(WARNING) << __func__ << ": reading of " << readByteCount
                      << " bytes of data from MQ failed";
         reply->status = STATUS_NOT_ENOUGH_DATA;
     }
-    reply->latencyMs = Module::kLatencyMs;
+    reply->latencyMs = latency;
     return !fatal;
 }
 
-template <class Metadata, class StreamWorker>
-StreamCommonImpl<Metadata, StreamWorker>::~StreamCommonImpl() {
+template <class Metadata>
+StreamCommonImpl<Metadata>::~StreamCommonImpl() {
     if (!isClosed()) {
         LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
         stopWorker();
@@ -507,8 +560,8 @@
     }
 }
 
-template <class Metadata, class StreamWorker>
-void StreamCommonImpl<Metadata, StreamWorker>::createStreamCommon(
+template <class Metadata>
+void StreamCommonImpl<Metadata>::createStreamCommon(
         const std::shared_ptr<StreamCommonInterface>& delegate) {
     if (mCommon != nullptr) {
         LOG(FATAL) << __func__ << ": attempting to create the common interface twice";
@@ -518,8 +571,8 @@
     AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::getStreamCommon(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon(
         std::shared_ptr<IStreamCommon>* _aidl_return) {
     if (mCommon == nullptr) {
         LOG(FATAL) << __func__ << ": the common interface was not created";
@@ -529,31 +582,30 @@
     return ndk::ScopedAStatus::ok();
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::updateHwAvSyncId(
-        int32_t in_hwAvSyncId) {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) {
     LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId;
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::getVendorParameters(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters(
         const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) {
     LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
     (void)_aidl_return;
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::setVendorParameters(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters(
         const std::vector<VendorParameter>& in_parameters, bool in_async) {
     LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size()
                << ", async: " << in_async;
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::addEffect(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect(
         const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
     if (in_effect == nullptr) {
         LOG(DEBUG) << __func__ << ": null effect";
@@ -563,8 +615,8 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::removeEffect(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect(
         const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
     if (in_effect == nullptr) {
         LOG(DEBUG) << __func__ << ": null effect";
@@ -574,16 +626,16 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::close() {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() {
     LOG(DEBUG) << __func__;
     if (!isClosed()) {
         stopWorker();
         LOG(DEBUG) << __func__ << ": joining the worker thread...";
-        mWorker.stop();
+        mWorker->stop();
         LOG(DEBUG) << __func__ << ": worker thread joined";
         mContext.reset();
-        mWorker.setClosed();
+        mWorker->setClosed();
         return ndk::ScopedAStatus::ok();
     } else {
         LOG(ERROR) << __func__ << ": stream was already closed";
@@ -591,8 +643,8 @@
     }
 }
 
-template <class Metadata, class StreamWorker>
-void StreamCommonImpl<Metadata, StreamWorker>::stopWorker() {
+template <class Metadata>
+void StreamCommonImpl<Metadata>::stopWorker() {
     if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
         LOG(DEBUG) << __func__ << ": asking the worker to exit...";
         auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
@@ -608,9 +660,8 @@
     }
 }
 
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::updateMetadata(
-        const Metadata& metadata) {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) {
     LOG(DEBUG) << __func__;
     if (!isClosed()) {
         mMetadata = metadata;
@@ -621,16 +672,11 @@
 }
 
 // static
-ndk::ScopedAStatus StreamIn::createInstance(const common::SinkMetadata& sinkMetadata,
-                                            StreamContext context,
-                                            const std::vector<MicrophoneInfo>& microphones,
-                                            std::shared_ptr<StreamIn>* result) {
-    auto stream = ndk::SharedRefBase::make<StreamIn>(sinkMetadata, std::move(context), microphones);
+ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) {
     if (auto status = stream->init(); !status.isOk()) {
         return status;
     }
     stream->createStreamCommon(stream);
-    *result = std::move(stream);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -645,8 +691,10 @@
 }  // namespace
 
 StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context,
+                   const DriverInterface::CreateInstance& createDriver,
+                   const StreamWorkerInterface::CreateInstance& createWorker,
                    const std::vector<MicrophoneInfo>& microphones)
-    : StreamCommonImpl<SinkMetadata, StreamInWorker>(sinkMetadata, std::move(context)),
+    : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker),
       mMicrophones(transformMicrophones(microphones)) {
     LOG(DEBUG) << __func__;
 }
@@ -704,23 +752,20 @@
 }
 
 // static
-ndk::ScopedAStatus StreamOut::createInstance(const SourceMetadata& sourceMetadata,
-                                             StreamContext context,
-                                             const std::optional<AudioOffloadInfo>& offloadInfo,
-                                             std::shared_ptr<StreamOut>* result) {
-    auto stream =
-            ndk::SharedRefBase::make<StreamOut>(sourceMetadata, std::move(context), offloadInfo);
+ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) {
     if (auto status = stream->init(); !status.isOk()) {
         return status;
     }
     stream->createStreamCommon(stream);
-    *result = std::move(stream);
     return ndk::ScopedAStatus::ok();
 }
 
 StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context,
+                     const DriverInterface::CreateInstance& createDriver,
+                     const StreamWorkerInterface::CreateInstance& createWorker,
                      const std::optional<AudioOffloadInfo>& offloadInfo)
-    : StreamCommonImpl<SourceMetadata, StreamOutWorker>(sourceMetadata, std::move(context)),
+    : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver,
+                                       createWorker),
       mOffloadInfo(offloadInfo) {
     LOG(DEBUG) << __func__;
 }
diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp
new file mode 100644
index 0000000..5442179
--- /dev/null
+++ b/audio/aidl/default/StreamStub.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+
+#include "core-impl/Module.h"
+#include "core-impl/StreamStub.h"
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+DriverStub::DriverStub(const StreamContext& context, bool isInput)
+    : mFrameSizeBytes(context.getFrameSize()), mIsInput(isInput) {}
+
+::android::status_t DriverStub::init() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::drain(StreamDescriptor::DrainMode) {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::flush() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::pause() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                         int32_t* latencyMs) {
+    usleep(3000);
+    if (mIsInput) {
+        uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
+        for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
+            byteBuffer[i] = std::rand() % 255;
+        }
+    }
+    *actualFrameCount = frameCount;
+    *latencyMs = Module::kLatencyMs;
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::standby() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+// static
+ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
+                                                StreamContext&& context,
+                                                const std::vector<MicrophoneInfo>& microphones,
+                                                std::shared_ptr<StreamIn>* result) {
+    std::shared_ptr<StreamIn> stream =
+            ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
+                           const std::vector<MicrophoneInfo>& microphones)
+    : StreamIn(
+              sinkMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverStub(ctx, true /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamInWorker(ctx, driver);
+              },
+              microphones) {}
+
+// static
+ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
+                                                 StreamContext&& context,
+                                                 const std::optional<AudioOffloadInfo>& offloadInfo,
+                                                 std::shared_ptr<StreamOut>* result) {
+    std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
+            sourceMetadata, std::move(context), offloadInfo);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
+                             const std::optional<AudioOffloadInfo>& offloadInfo)
+    : StreamOut(
+              sourceMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverStub(ctx, false /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamOutWorker(ctx, driver);
+              },
+              offloadInfo) {}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp
index d873178..ad22470 100644
--- a/audio/aidl/default/Telephony.cpp
+++ b/audio/aidl/default/Telephony.cpp
@@ -14,14 +14,18 @@
  * limitations under the License.
  */
 
-#include <android/binder_to_string.h>
 #define LOG_TAG "AHAL_Telephony"
 #include <android-base/logging.h>
 
+#include <Utils.h>
+#include <android/binder_to_string.h>
+
 #include "core-impl/Telephony.h"
 
+using aidl::android::media::audio::common::AudioMode;
 using aidl::android::media::audio::common::Boolean;
 using aidl::android::media::audio::common::Float;
+using android::hardware::audio::common::isValidAudioMode;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -38,6 +42,10 @@
 }
 
 ndk::ScopedAStatus Telephony::switchAudioMode(AudioMode in_mode) {
+    if (!isValidAudioMode(in_mode)) {
+        LOG(ERROR) << __func__ << ": invalid mode " << toString(in_mode);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
     if (std::find(mSupportedAudioModes.begin(), mSupportedAudioModes.end(), in_mode) !=
         mSupportedAudioModes.end()) {
         LOG(DEBUG) << __func__ << ": " << toString(in_mode);
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index e460f89..6714a7e 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -40,6 +40,7 @@
         <library name="nssw" path="libnssw.so"/>
         <library name="env_reverbsw" path="libenvreverbsw.so"/>
         <library name="preset_reverbsw" path="libpresetreverbsw.so"/>
+        <library name="reverb" path="libreverbaidl.so"/>
         <library name="virtualizersw" path="libvirtualizersw.so"/>
         <library name="visualizer" path="libvisualizeraidl.so"/>
         <library name="volumesw" path="libvolumesw.so"/>
@@ -78,6 +79,10 @@
         <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
         <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
         <effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
+        <effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
+        <effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
+        <effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
+        <effect name="reverb_pre_ins" library="reverb" uuid="172cdf00-a3bc-11df-a72f-0002a5d5c51b"/>
         <effectProxy name="virtualizer" uuid="d3467faa-acc7-4d34-acaf-0002a5d5c51b">
             <libsw library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
             <libsw library="bundle" uuid="1d4033c0-8557-11df-9f2d-0002a5d5c51b"/>
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 9d7159a..905dba4 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -60,8 +60,18 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
-const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {
-        .maxDecayTimeMs = EnvironmentalReverb::MAX_DECAY_TIME_MS};
+const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {.minRoomLevelMb = -6000,
+                                                                  .maxRoomLevelMb = 0,
+                                                                  .minRoomHfLevelMb = -4000,
+                                                                  .maxRoomHfLevelMb = 0,
+                                                                  .maxDecayTimeMs = 7000,
+                                                                  .minDecayHfRatioPm = 100,
+                                                                  .maxDecayHfRatioPm = 2000,
+                                                                  .minLevelMb = -6000,
+                                                                  .maxLevelMb = 0,
+                                                                  .maxDelayMs = 65,
+                                                                  .maxDiffusionPm = 1000,
+                                                                  .maxDensityPm = 1000};
 const Descriptor EnvReverbSw::kDescriptor = {
         .common = {.id = {.type = kEnvReverbTypeUUID,
                           .uuid = kEnvReverbSwImplUUID,
@@ -251,4 +261,88 @@
     return {STATUS_OK, samples, samples};
 }
 
+RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
+    if (roomLevel < EnvReverbSw::kCapability.minRoomLevelMb ||
+        roomLevel > EnvReverbSw::kCapability.maxRoomLevelMb) {
+        LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new room level
+    mRoomLevel = roomLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
+    if (roomHfLevel < EnvReverbSw::kCapability.minRoomHfLevelMb ||
+        roomHfLevel > EnvReverbSw::kCapability.maxRoomHfLevelMb) {
+        LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new room HF level
+    mRoomHfLevel = roomHfLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
+    if (decayTime < 0 || decayTime > EnvReverbSw::kCapability.maxDecayTimeMs) {
+        LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new decay time
+    mDecayTime = decayTime;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
+    if (decayHfRatio < EnvReverbSw::kCapability.minDecayHfRatioPm ||
+        decayHfRatio > EnvReverbSw::kCapability.maxDecayHfRatioPm) {
+        LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new decay HF ratio
+    mDecayHfRatio = decayHfRatio;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErLevel(int level) {
+    if (level < EnvReverbSw::kCapability.minLevelMb ||
+        level > EnvReverbSw::kCapability.maxLevelMb) {
+        LOG(ERROR) << __func__ << " invalid level: " << level;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new level
+    mLevel = level;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDelay(int delay) {
+    if (delay < 0 || delay > EnvReverbSw::kCapability.maxDelayMs) {
+        LOG(ERROR) << __func__ << " invalid delay: " << delay;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new delay
+    mDelay = delay;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
+    if (diffusion < 0 || diffusion > EnvReverbSw::kCapability.maxDiffusionPm) {
+        LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new diffusion
+    mDiffusion = diffusion;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDensity(int density) {
+    if (density < 0 || density > EnvReverbSw::kCapability.maxDensityPm) {
+        LOG(ERROR) << __func__ << " invalid density: " << density;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    // TODO : Add implementation to apply new density
+    mDensity = density;
+    return RetCode::SUCCESS;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index f521215..77f384e 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -33,100 +33,28 @@
         LOG(DEBUG) << __func__;
     }
 
-    RetCode setErRoomLevel(int roomLevel) {
-        if (roomLevel < EnvironmentalReverb::MIN_ROOM_LEVEL_MB ||
-            roomLevel > EnvironmentalReverb::MAX_ROOM_LEVEL_MB) {
-            LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new room level
-        mRoomLevel = roomLevel;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErRoomLevel(int roomLevel);
     int getErRoomLevel() const { return mRoomLevel; }
 
-    RetCode setErRoomHfLevel(int roomHfLevel) {
-        if (roomHfLevel < EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB ||
-            roomHfLevel > EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB) {
-            LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new room HF level
-        mRoomHfLevel = roomHfLevel;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErRoomHfLevel(int roomHfLevel);
     int getErRoomHfLevel() const { return mRoomHfLevel; }
 
-    RetCode setErDecayTime(int decayTime) {
-        if (decayTime < EnvironmentalReverb::MIN_DECAY_TIME_MS ||
-            decayTime > EnvironmentalReverb::MAX_DECAY_TIME_MS) {
-            LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new decay time
-        mDecayTime = decayTime;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErDecayTime(int decayTime);
     int getErDecayTime() const { return mDecayTime; }
 
-    RetCode setErDecayHfRatio(int decayHfRatio) {
-        if (decayHfRatio < EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM ||
-            decayHfRatio > EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM) {
-            LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new decay HF ratio
-        mDecayHfRatio = decayHfRatio;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErDecayHfRatio(int decayHfRatio);
     int getErDecayHfRatio() const { return mDecayHfRatio; }
 
-    RetCode setErLevel(int level) {
-        if (level < EnvironmentalReverb::MIN_LEVEL_MB ||
-            level > EnvironmentalReverb::MAX_LEVEL_MB) {
-            LOG(ERROR) << __func__ << " invalid level: " << level;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new level
-        mLevel = level;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErLevel(int level);
     int getErLevel() const { return mLevel; }
 
-    RetCode setErDelay(int delay) {
-        if (delay < EnvironmentalReverb::MIN_DELAY_MS ||
-            delay > EnvironmentalReverb::MAX_DELAY_MS) {
-            LOG(ERROR) << __func__ << " invalid delay: " << delay;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new delay
-        mDelay = delay;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErDelay(int delay);
     int getErDelay() const { return mDelay; }
 
-    RetCode setErDiffusion(int diffusion) {
-        if (diffusion < EnvironmentalReverb::MIN_DIFFUSION_PM ||
-            diffusion > EnvironmentalReverb::MAX_DIFFUSION_PM) {
-            LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new diffusion
-        mDiffusion = diffusion;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErDiffusion(int diffusion);
     int getErDiffusion() const { return mDiffusion; }
 
-    RetCode setErDensity(int density) {
-        if (density < EnvironmentalReverb::MIN_DENSITY_PM ||
-            density > EnvironmentalReverb::MAX_DENSITY_PM) {
-            LOG(ERROR) << __func__ << " invalid density: " << density;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new density
-        mDensity = density;
-        return RetCode::SUCCESS;
-    }
+    RetCode setErDensity(int density);
     int getErDensity() const { return mDensity; }
 
     RetCode setErBypass(bool bypass) {
@@ -137,14 +65,14 @@
     bool getErBypass() const { return mBypass; }
 
   private:
-    int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB;       // Default room level
-    int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;  // Default room hf level
+    int mRoomLevel = -6000;                                        // Default room level
+    int mRoomHfLevel = 0;                                          // Default room hf level
     int mDecayTime = 1000;                                         // Default decay time
     int mDecayHfRatio = 500;                                       // Default decay hf ratio
-    int mLevel = EnvironmentalReverb::MIN_LEVEL_MB;                // Default level
+    int mLevel = -6000;                                            // Default level
     int mDelay = 40;                                               // Default delay
-    int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM;        // Default diffusion
-    int mDensity = EnvironmentalReverb::MAX_DENSITY_PM;            // Default density
+    int mDiffusion = 1000;                                         // Default diffusion
+    int mDensity = 1000;                                           // Default density
     bool mBypass = false;                                          // Default bypass
 };
 
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 000a704..3cce769 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -92,7 +92,7 @@
     ndk::ScopedAStatus setMicMute(bool in_mute) override;
     ndk::ScopedAStatus getMicrophones(std::vector<MicrophoneInfo>* _aidl_return) override;
     ndk::ScopedAStatus updateAudioMode(
-            ::aidl::android::hardware::audio::core::AudioMode in_mode) override;
+            ::aidl::android::media::audio::common::AudioMode in_mode) override;
     ndk::ScopedAStatus updateScreenRotation(
             ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
     ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
@@ -115,6 +115,7 @@
     ndk::ScopedAStatus createStreamContext(
             int32_t in_portConfigId, int64_t in_bufferSizeFrames,
             std::shared_ptr<IStreamCallback> asyncCallback,
+            std::shared_ptr<IStreamOutEventCallback> outEventCallback,
             ::aidl::android::hardware::audio::core::StreamContext* out_context);
     std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices(
             int32_t portConfigId);
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 2cf5951..7cd4259 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -31,12 +31,14 @@
 #include <aidl/android/hardware/audio/core/BnStreamIn.h>
 #include <aidl/android/hardware/audio/core/BnStreamOut.h>
 #include <aidl/android/hardware/audio/core/IStreamCallback.h>
+#include <aidl/android/hardware/audio/core/IStreamOutEventCallback.h>
 #include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
 #include <aidl/android/hardware/audio/core/StreamDescriptor.h>
 #include <aidl/android/media/audio/common/AudioDevice.h>
 #include <aidl/android/media/audio/common/AudioOffloadInfo.h>
 #include <fmq/AidlMessageQueue.h>
 #include <system/thread_defs.h>
+#include <utils/Errors.h>
 
 #include "core-impl/utils.h"
 
@@ -76,6 +78,7 @@
                   const ::aidl::android::media::audio::common::AudioFormatDescription& format,
                   const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout,
                   std::unique_ptr<DataMQ> dataMQ, std::shared_ptr<IStreamCallback> asyncCallback,
+                  std::shared_ptr<IStreamOutEventCallback> outEventCallback,
                   DebugParameters debugParameters)
         : mCommandMQ(std::move(commandMQ)),
           mInternalCommandCookie(std::rand()),
@@ -84,6 +87,7 @@
           mChannelLayout(channelLayout),
           mDataMQ(std::move(dataMQ)),
           mAsyncCallback(asyncCallback),
+          mOutEventCallback(outEventCallback),
           mDebugParameters(debugParameters) {}
     StreamContext(StreamContext&& other)
         : mCommandMQ(std::move(other.mCommandMQ)),
@@ -93,6 +97,7 @@
           mChannelLayout(other.mChannelLayout),
           mDataMQ(std::move(other.mDataMQ)),
           mAsyncCallback(std::move(other.mAsyncCallback)),
+          mOutEventCallback(std::move(other.mOutEventCallback)),
           mDebugParameters(std::move(other.mDebugParameters)) {}
     StreamContext& operator=(StreamContext&& other) {
         mCommandMQ = std::move(other.mCommandMQ);
@@ -102,6 +107,7 @@
         mChannelLayout = std::move(other.mChannelLayout);
         mDataMQ = std::move(other.mDataMQ);
         mAsyncCallback = std::move(other.mAsyncCallback);
+        mOutEventCallback = std::move(other.mOutEventCallback);
         mDebugParameters = std::move(other.mDebugParameters);
         return *this;
     }
@@ -120,6 +126,9 @@
     bool getForceSynchronousDrain() const { return mDebugParameters.forceSynchronousDrain; }
     size_t getFrameSize() const;
     int getInternalCommandCookie() const { return mInternalCommandCookie; }
+    std::shared_ptr<IStreamOutEventCallback> getOutEventCallback() const {
+        return mOutEventCallback;
+    }
     ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
     int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
     bool isValid() const;
@@ -133,9 +142,24 @@
     ::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
     std::unique_ptr<DataMQ> mDataMQ;
     std::shared_ptr<IStreamCallback> mAsyncCallback;
+    std::shared_ptr<IStreamOutEventCallback> mOutEventCallback;  // Only used by output streams
     DebugParameters mDebugParameters;
 };
 
+struct DriverInterface {
+    using CreateInstance = std::function<DriverInterface*(const StreamContext&)>;
+    virtual ~DriverInterface() = default;
+    // This function is called once, on the main thread, before starting the worker thread.
+    virtual ::android::status_t init() = 0;
+    // All the functions below are called on the worker thread.
+    virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
+    virtual ::android::status_t flush() = 0;
+    virtual ::android::status_t pause() = 0;
+    virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                         int32_t* latencyMs) = 0;
+    virtual ::android::status_t standby() = 0;
+};
+
 class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic {
   public:
     bool isClosed() const {
@@ -145,8 +169,11 @@
     void setIsConnected(bool connected) { mIsConnected = connected; }
 
   protected:
-    explicit StreamWorkerCommonLogic(const StreamContext& context)
-        : mInternalCommandCookie(context.getInternalCommandCookie()),
+    using DataBufferElement = int8_t;
+
+    StreamWorkerCommonLogic(const StreamContext& context, DriverInterface* driver)
+        : mDriver(driver),
+          mInternalCommandCookie(context.getInternalCommandCookie()),
           mFrameSize(context.getFrameSize()),
           mCommandMQ(context.getCommandMQ()),
           mReplyMQ(context.getReplyMQ()),
@@ -164,6 +191,7 @@
         mTransientStateStart = std::chrono::steady_clock::now();
     }
 
+    DriverInterface* const mDriver;
     // Atomic fields are used both by the main and worker threads.
     std::atomic<bool> mIsConnected = false;
     static_assert(std::atomic<StreamDescriptor::State>::is_always_lock_free);
@@ -171,9 +199,9 @@
     // All fields are used on the worker thread only.
     const int mInternalCommandCookie;
     const size_t mFrameSize;
-    StreamContext::CommandMQ* mCommandMQ;
-    StreamContext::ReplyMQ* mReplyMQ;
-    StreamContext::DataMQ* mDataMQ;
+    StreamContext::CommandMQ* const mCommandMQ;
+    StreamContext::ReplyMQ* const mReplyMQ;
+    StreamContext::DataMQ* const mDataMQ;
     std::shared_ptr<IStreamCallback> mAsyncCallback;
     const std::chrono::duration<int, std::milli> mTransientStateDelayMs;
     std::chrono::time_point<std::chrono::steady_clock> mTransientStateStart;
@@ -181,15 +209,46 @@
     const bool mForceSynchronousDrain;
     // We use an array and the "size" field instead of a vector to be able to detect
     // memory allocation issues.
-    std::unique_ptr<int8_t[]> mDataBuffer;
+    std::unique_ptr<DataBufferElement[]> mDataBuffer;
     size_t mDataBufferSize;
     long mFrameCount = 0;
 };
 
+// This interface is used to decouple stream implementations from a concrete StreamWorker
+// implementation.
+struct StreamWorkerInterface {
+    using CreateInstance = std::function<StreamWorkerInterface*(const StreamContext& context,
+                                                                DriverInterface* driver)>;
+    virtual ~StreamWorkerInterface() = default;
+    virtual bool isClosed() const = 0;
+    virtual void setIsConnected(bool isConnected) = 0;
+    virtual void setClosed() = 0;
+    virtual bool start() = 0;
+    virtual void stop() = 0;
+};
+
+template <class WorkerLogic>
+class StreamWorkerImpl : public StreamWorkerInterface,
+                         public ::android::hardware::audio::common::StreamWorker<WorkerLogic> {
+    using WorkerImpl = ::android::hardware::audio::common::StreamWorker<WorkerLogic>;
+
+  public:
+    StreamWorkerImpl(const StreamContext& context, DriverInterface* driver)
+        : WorkerImpl(context, driver) {}
+    bool isClosed() const override { return WorkerImpl::isClosed(); }
+    void setIsConnected(bool isConnected) override { WorkerImpl::setIsConnected(isConnected); }
+    void setClosed() override { WorkerImpl::setClosed(); }
+    bool start() override {
+        return WorkerImpl::start(WorkerImpl::kThreadName, ANDROID_PRIORITY_AUDIO);
+    }
+    void stop() override { return WorkerImpl::stop(); }
+};
+
 class StreamInWorkerLogic : public StreamWorkerCommonLogic {
   public:
     static const std::string kThreadName;
-    explicit StreamInWorkerLogic(const StreamContext& context) : StreamWorkerCommonLogic(context) {}
+    StreamInWorkerLogic(const StreamContext& context, DriverInterface* driver)
+        : StreamWorkerCommonLogic(context, driver) {}
 
   protected:
     Status cycle() override;
@@ -197,21 +256,23 @@
   private:
     bool read(size_t clientSize, StreamDescriptor::Reply* reply);
 };
-using StreamInWorker = ::android::hardware::audio::common::StreamWorker<StreamInWorkerLogic>;
+using StreamInWorker = StreamWorkerImpl<StreamInWorkerLogic>;
 
 class StreamOutWorkerLogic : public StreamWorkerCommonLogic {
   public:
     static const std::string kThreadName;
-    explicit StreamOutWorkerLogic(const StreamContext& context)
-        : StreamWorkerCommonLogic(context) {}
+    StreamOutWorkerLogic(const StreamContext& context, DriverInterface* driver)
+        : StreamWorkerCommonLogic(context, driver), mEventCallback(context.getOutEventCallback()) {}
 
   protected:
     Status cycle() override;
 
   private:
     bool write(size_t clientSize, StreamDescriptor::Reply* reply);
+
+    std::shared_ptr<IStreamOutEventCallback> mEventCallback;
 };
-using StreamOutWorker = ::android::hardware::audio::common::StreamWorker<StreamOutWorkerLogic>;
+using StreamOutWorker = StreamWorkerImpl<StreamOutWorkerLogic>;
 
 // This provides a C++ interface with methods of the IStreamCommon Binder interface,
 // but intentionally does not inherit from it. This is needed to avoid inheriting
@@ -283,7 +344,7 @@
     std::weak_ptr<StreamCommonInterface> mDelegate;
 };
 
-template <class Metadata, class StreamWorker>
+template <class Metadata>
 class StreamCommonImpl : public StreamCommonInterface {
   public:
     ndk::ScopedAStatus close() override;
@@ -301,21 +362,25 @@
 
     ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return);
     ndk::ScopedAStatus init() {
-        return mWorker.start(StreamWorker::kThreadName, ANDROID_PRIORITY_AUDIO)
-                       ? ndk::ScopedAStatus::ok()
-                       : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        return mWorker->start() ? ndk::ScopedAStatus::ok()
+                                : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
-    bool isClosed() const { return mWorker.isClosed(); }
+    bool isClosed() const { return mWorker->isClosed(); }
     void setIsConnected(
             const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
-        mWorker.setIsConnected(!devices.empty());
+        mWorker->setIsConnected(!devices.empty());
         mConnectedDevices = devices;
     }
     ndk::ScopedAStatus updateMetadata(const Metadata& metadata);
 
   protected:
-    StreamCommonImpl(const Metadata& metadata, StreamContext&& context)
-        : mMetadata(metadata), mContext(std::move(context)), mWorker(mContext) {}
+    StreamCommonImpl(const Metadata& metadata, StreamContext&& context,
+                     const DriverInterface::CreateInstance& createDriver,
+                     const StreamWorkerInterface::CreateInstance& createWorker)
+        : mMetadata(metadata),
+          mContext(std::move(context)),
+          mDriver(createDriver(mContext)),
+          mWorker(createWorker(mContext, mDriver.get())) {}
     ~StreamCommonImpl();
     void stopWorker();
     void createStreamCommon(const std::shared_ptr<StreamCommonInterface>& delegate);
@@ -324,16 +389,16 @@
     ndk::SpAIBinder mCommonBinder;
     Metadata mMetadata;
     StreamContext mContext;
-    StreamWorker mWorker;
+    std::unique_ptr<DriverInterface> mDriver;
+    std::unique_ptr<StreamWorkerInterface> mWorker;
     std::vector<::aidl::android::media::audio::common::AudioDevice> mConnectedDevices;
 };
 
-class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
-                                         StreamInWorker>,
+class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>,
                  public BnStreamIn {
     ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
-        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
-                                StreamInWorker>::getStreamCommon(_aidl_return);
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+                getStreamCommon(_aidl_return);
     }
     ndk::ScopedAStatus getActiveMicrophones(
             std::vector<MicrophoneDynamicInfo>* _aidl_return) override;
@@ -343,42 +408,46 @@
     ndk::ScopedAStatus setMicrophoneFieldDimension(float in_zoom) override;
     ndk::ScopedAStatus updateMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata&
                                               in_sinkMetadata) override {
-        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
-                                StreamInWorker>::updateMetadata(in_sinkMetadata);
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+                updateMetadata(in_sinkMetadata);
     }
     ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
     ndk::ScopedAStatus setHwGain(const std::vector<float>& in_channelGains) override;
 
-  public:
-    static ndk::ScopedAStatus createInstance(
-            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-            StreamContext context, const std::vector<MicrophoneInfo>& microphones,
-            std::shared_ptr<StreamIn>* result);
-
-  private:
+  protected:
     friend class ndk::SharedRefBase;
+
+    static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamIn>& stream);
+
     StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-             StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+             StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+             const StreamWorkerInterface::CreateInstance& createWorker,
+             const std::vector<MicrophoneInfo>& microphones);
     void createStreamCommon(const std::shared_ptr<StreamIn>& myPtr) {
-        StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
-                         StreamInWorker>::createStreamCommon(myPtr);
+        StreamCommonImpl<
+                ::aidl::android::hardware::audio::common::SinkMetadata>::createStreamCommon(myPtr);
     }
 
     const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones;
+
+  public:
+    using CreateInstance = std::function<ndk::ScopedAStatus(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+            std::shared_ptr<StreamIn>* result)>;
 };
 
-class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
-                                          StreamOutWorker>,
+class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>,
                   public BnStreamOut {
     ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
-        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
-                                StreamOutWorker>::getStreamCommon(_aidl_return);
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                getStreamCommon(_aidl_return);
     }
     ndk::ScopedAStatus updateMetadata(
             const ::aidl::android::hardware::audio::common::SourceMetadata& in_sourceMetadata)
             override {
-        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
-                                StreamOutWorker>::updateMetadata(in_sourceMetadata);
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                updateMetadata(in_sourceMetadata);
     }
     ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
     ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
@@ -400,26 +469,31 @@
             override;
     ndk::ScopedAStatus selectPresentation(int32_t in_presentationId, int32_t in_programId) override;
 
-  public:
-    static ndk::ScopedAStatus createInstance(
-            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
-            StreamContext context,
-            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
-                    offloadInfo,
-            std::shared_ptr<StreamOut>* result);
-
-  private:
-    friend class ndk::SharedRefBase;
-    StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
-              StreamContext&& context,
-              const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
-                      offloadInfo);
     void createStreamCommon(const std::shared_ptr<StreamOut>& myPtr) {
-        StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
-                         StreamOutWorker>::createStreamCommon(myPtr);
+        StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                createStreamCommon(myPtr);
     }
 
+  protected:
+    friend class ndk::SharedRefBase;
+
+    static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamOut>& stream);
+
+    StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+              StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+              const StreamWorkerInterface::CreateInstance& createWorker,
+              const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                      offloadInfo);
+
     std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo;
+
+  public:
+    using CreateInstance = std::function<ndk::ScopedAStatus(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            StreamContext&& context,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo,
+            std::shared_ptr<StreamOut>* result)>;
 };
 
 class StreamWrapper {
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
new file mode 100644
index 0000000..98a062a
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverStub : public DriverInterface {
+  public:
+    DriverStub(const StreamContext& context, bool isInput);
+    ::android::status_t init() override;
+    ::android::status_t drain(StreamDescriptor::DrainMode) override;
+    ::android::status_t flush() override;
+    ::android::status_t pause() override;
+    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                 int32_t* latencyMs) override;
+    ::android::status_t standby() override;
+
+  private:
+    const size_t mFrameSizeBytes;
+    const bool mIsInput;
+};
+
+class StreamInStub final : public StreamIn {
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+            std::shared_ptr<StreamIn>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamInStub(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+                 StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+};
+
+class StreamOutStub final : public StreamOut {
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            StreamContext&& context,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo,
+            std::shared_ptr<StreamOut>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamOutStub(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+                  StreamContext&& context,
+                  const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                          offloadInfo);
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Telephony.h b/audio/aidl/default/include/core-impl/Telephony.h
index 0936172..0f8e93f 100644
--- a/audio/aidl/default/include/core-impl/Telephony.h
+++ b/audio/aidl/default/include/core-impl/Telephony.h
@@ -27,13 +27,20 @@
     Telephony();
 
   private:
-    ndk::ScopedAStatus getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) override;
-    ndk::ScopedAStatus switchAudioMode(AudioMode in_mode) override;
+    ndk::ScopedAStatus getSupportedAudioModes(
+            std::vector<::aidl::android::media::audio::common::AudioMode>* _aidl_return) override;
+    ndk::ScopedAStatus switchAudioMode(
+            ::aidl::android::media::audio::common::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()};
+    const std::vector<::aidl::android::media::audio::common::AudioMode> mSupportedAudioModes = {
+            ::aidl::android::media::audio::common::AudioMode::NORMAL,
+            ::aidl::android::media::audio::common::AudioMode::RINGTONE,
+            ::aidl::android::media::audio::common::AudioMode::IN_CALL,
+            ::aidl::android::media::audio::common::AudioMode::IN_COMMUNICATION,
+            // Omit CALL_SCREEN for a better VTS coverage.
+    };
     TelecomConfig mTelecomConfig;
 };
 
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index a3e7ff2..7bbf19e 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -91,11 +91,13 @@
     int getSessionId() { return mSessionId; }
 
     virtual RetCode setOutputDevice(
-            const aidl::android::media::audio::common::AudioDeviceDescription& device) {
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+                    device) {
         mOutputDevice = device;
         return RetCode::SUCCESS;
     }
-    virtual aidl::android::media::audio::common::AudioDeviceDescription getOutputDevice() {
+    virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
+    getOutputDevice() {
         return mOutputDevice;
     }
 
@@ -133,7 +135,7 @@
     size_t mInputFrameSize;
     size_t mOutputFrameSize;
     Parameter::Common mCommon;
-    aidl::android::media::audio::common::AudioDeviceDescription mOutputDevice;
+    std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
     aidl::android::media::audio::common::AudioMode mMode;
     aidl::android::media::audio::common::AudioSource mSource;
     Parameter::VolumeStereo mVolumeStereo;
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
index 1a60829..7703091 100644
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ b/audio/aidl/default/include/effect-impl/EffectUUID.h
@@ -189,6 +189,18 @@
                                                0x11ed,
                                                0x9b6a,
                                                {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 4a387fc0-8ab3-11df-8bad-0002a5d5c51b
+static const AudioUuid kAuxEnvReverbImplUUID = {static_cast<int32_t>(0x4a387fc0),
+                                                0x8ab3,
+                                                0x11df,
+                                                0x8bad,
+                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// c7a511a0-a3bb-11df-860e-0002a5d5c51b
+static const AudioUuid kInsertEnvReverbImplUUID = {static_cast<int32_t>(0xc7a511a0),
+                                                   0xa3bb,
+                                                   0x11df,
+                                                   0x860e,
+                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
 // 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
 static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
                                                     0x8e06,
@@ -213,6 +225,18 @@
                                                   0x11ed,
                                                   0x9b6a,
                                                   {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// f29a1400-a3bb-11df-8ddc-0002a5d5c51b
+static const AudioUuid kAuxPresetReverbImplUUID = {static_cast<int32_t>(0xf29a1400),
+                                                   0xa3bb,
+                                                   0x11df,
+                                                   0x8ddc,
+                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 172cdf00-a3bc-11df-a72f-0002a5d5c51b
+static const AudioUuid kInsertPresetReverbImplUUID = {static_cast<int32_t>(0x172cdf00),
+                                                      0xa3bc,
+                                                      0x11df,
+                                                      0xa72f,
+                                                      {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
 // 37cc2c00-dddd-11db-8577-0002a5d5c51b
 static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
                                                0xdddd,
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
index 04bd1bb..b32ec56 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -101,7 +101,7 @@
 
     ndk::ScopedAStatus destroyEffectImpl(const std::shared_ptr<IEffect>& in_handle);
     void cleanupEffectMap();
-    void openEffectLibrary(const ::aidl::android::media::audio::common::AudioUuid& impl,
+    bool openEffectLibrary(const ::aidl::android::media::audio::common::AudioUuid& impl,
                            const std::string& libName);
     void createIdentityWithConfig(
             const EffectConfig::LibraryUuid& configLib,
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index d4f2811..a8febc5 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -54,7 +54,6 @@
 using aidl::android::hardware::audio::common::RecordTrackMetadata;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
-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;
@@ -78,6 +77,7 @@
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioLatencyMode;
+using aidl::android::media::audio::common::AudioMode;
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPlaybackRate;
 using aidl::android::media::audio::common::AudioPort;
@@ -93,6 +93,7 @@
 using android::hardware::audio::common::getChannelCount;
 using android::hardware::audio::common::isBitPositionFlagSet;
 using android::hardware::audio::common::isTelephonyDeviceType;
+using android::hardware::audio::common::isValidAudioMode;
 using android::hardware::audio::common::StreamLogic;
 using android::hardware::audio::common::StreamWorker;
 using ndk::enum_range;
@@ -1805,7 +1806,11 @@
 
 TEST_P(AudioCoreModule, UpdateAudioMode) {
     for (const auto mode : ::ndk::enum_range<AudioMode>()) {
-        EXPECT_IS_OK(module->updateAudioMode(mode)) << toString(mode);
+        if (isValidAudioMode(mode)) {
+            EXPECT_IS_OK(module->updateAudioMode(mode)) << toString(mode);
+        } else {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->updateAudioMode(mode)) << toString(mode);
+        }
     }
     EXPECT_IS_OK(module->updateAudioMode(AudioMode::NORMAL));
 }
@@ -1994,6 +1999,9 @@
     }
     std::vector<AudioMode> modes1;
     ASSERT_IS_OK(telephony->getSupportedAudioModes(&modes1));
+    for (const auto mode : modes1) {
+        EXPECT_TRUE(isValidAudioMode(mode)) << toString(mode);
+    }
     const std::vector<AudioMode> kMandatoryModes = {AudioMode::NORMAL, AudioMode::RINGTONE,
                                                     AudioMode::IN_CALL,
                                                     AudioMode::IN_COMMUNICATION};
@@ -2025,7 +2033,9 @@
         unsupportedModes.erase(mode);
     }
     for (const auto mode : unsupportedModes) {
-        EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, telephony->switchAudioMode(mode)) << toString(mode);
+        EXPECT_STATUS(isValidAudioMode(mode) ? EX_UNSUPPORTED_OPERATION : EX_ILLEGAL_ARGUMENT,
+                      telephony->switchAudioMode(mode))
+                << toString(mode);
     }
 }
 
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 8938618..c5a0943 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -47,6 +47,10 @@
 using aidl::android::hardware::audio::effect::IFactory;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioSource;
 
 enum ParamName { PARAM_INSTANCE_NAME };
 using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
@@ -73,6 +77,13 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+
+    void setAndGetParameter(Parameter::Id id, const Parameter& set) {
+        Parameter get;
+        EXPECT_IS_OK(mEffect->setParameter(set));
+        EXPECT_IS_OK(mEffect->getParameter(id, &get));
+        EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+    }
 };
 
 TEST_P(AudioEffectTest, SetupAndTearDown) {
@@ -392,14 +403,8 @@
 
     Parameter::Common common = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
-    Parameter get = Parameter(), set = Parameter();
-    set.set<Parameter::common>(common);
-    EXPECT_IS_OK(mEffect->setParameter(set));
-
-    Parameter::Id id;
-    id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -414,14 +419,8 @@
 
     Parameter::Common common = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
-    Parameter get = Parameter(), set = Parameter();
-    set.set<Parameter::common>(common);
-    EXPECT_IS_OK(mEffect->setParameter(set));
-
-    Parameter::Id id;
-    id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
@@ -439,14 +438,8 @@
 
     Parameter::Common common = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
-    Parameter get = Parameter(), set = Parameter();
-    set.set<Parameter::common>(common);
-    EXPECT_IS_OK(mEffect->setParameter(set));
-
-    Parameter::Id id;
-    id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -461,18 +454,11 @@
 
     Parameter::Common common = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
-    Parameter get = Parameter(), set = Parameter();
-    set.set<Parameter::common>(common);
-    EXPECT_IS_OK(mEffect->setParameter(set));
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-
-    Parameter::Id id;
-    id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
-
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
@@ -487,21 +473,102 @@
 
     Parameter::Common common = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
-    Parameter get = Parameter(), set = Parameter();
-    set.set<Parameter::common>(common);
-    EXPECT_IS_OK(mEffect->setParameter(set));
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    Parameter::Id id;
-    id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
+
+// Set and get AudioDeviceDescription in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterDeviceDescription) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    std::vector<AudioDeviceDescription> deviceDescs = {
+            {.type = AudioDeviceType::IN_DEFAULT,
+             .connection = AudioDeviceDescription::CONNECTION_ANALOG},
+            {.type = AudioDeviceType::IN_DEVICE,
+             .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}};
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::deviceDescription);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::deviceDescription>(deviceDescs)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioMode in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioMode) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::mode);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::NORMAL)));
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::IN_COMMUNICATION)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioSource in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioSource) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::source);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::source>(AudioSource::DEFAULT)));
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(
+            id, Parameter::make<Parameter::source>(AudioSource::VOICE_RECOGNITION)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get VolumeStereo in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterVolume) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter::VolumeStereo volume = {.left = 10.0, .right = 10.0};
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::volumeStereo>(volume)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
 /// Data processing test
 // Send data to effects and expect it to be consumed by checking statusMQ.
 TEST_P(AudioEffectTest, ConsumeDataInProcessingState) {
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index e99c4a4..82c8757 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -18,6 +18,7 @@
 
 #include <Utils.h>
 #include <aidl/Vintf.h>
+#include <unordered_set>
 #include "EffectHelper.h"
 
 using namespace android;
@@ -38,30 +39,6 @@
  * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
  * EX_ILLEGAL_ARGUMENT.
  */
-const std::vector<int> kRoomLevelValues = {
-        EnvironmentalReverb::MIN_ROOM_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_LEVEL_MB,
-        EnvironmentalReverb::MAX_ROOM_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_LEVEL_MB + 1};
-const std::vector<int> kRoomHfLevelValues = {
-        EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB,
-        EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB + 1};
-const std::vector<int> kDecayTimeValues = {
-        EnvironmentalReverb::MIN_DECAY_TIME_MS - 1, EnvironmentalReverb::MIN_DECAY_TIME_MS,
-        EnvironmentalReverb::MAX_DECAY_TIME_MS, EnvironmentalReverb::MAX_DECAY_TIME_MS + 1};
-const std::vector<int> kDecayHfRatioValues = {
-        EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM - 1, EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM,
-        EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM, EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM + 1};
-const std::vector<int> kLevelValues = {
-        EnvironmentalReverb::MIN_LEVEL_MB - 1, EnvironmentalReverb::MIN_LEVEL_MB,
-        EnvironmentalReverb::MAX_LEVEL_MB, EnvironmentalReverb::MAX_LEVEL_MB + 1};
-const std::vector<int> kDelayValues = {
-        EnvironmentalReverb::MIN_DELAY_MS - 1, EnvironmentalReverb::MIN_DELAY_MS,
-        EnvironmentalReverb::MAX_DELAY_MS, EnvironmentalReverb::MAX_DELAY_MS + 1};
-const std::vector<int> kDiffusionValues = {
-        EnvironmentalReverb::MIN_DIFFUSION_PM - 1, EnvironmentalReverb::MIN_DIFFUSION_PM,
-        EnvironmentalReverb::MAX_DIFFUSION_PM, EnvironmentalReverb::MAX_DIFFUSION_PM + 1};
-const std::vector<int> kDensityValues = {
-        EnvironmentalReverb::MIN_DENSITY_PM - 1, EnvironmentalReverb::MIN_DENSITY_PM,
-        EnvironmentalReverb::MAX_DENSITY_PM, EnvironmentalReverb::MAX_DENSITY_PM + 1};
 
 class EnvironmentalReverbHelper : public EffectHelper {
   public:
@@ -88,8 +65,7 @@
     }
 
     Parameter::Specific getDefaultParamSpecific() {
-        EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(
-                EnvironmentalReverb::MIN_ROOM_LEVEL_MB);
+        EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(-6000);
         Parameter::Specific specific =
                 Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
         return specific;
@@ -99,14 +75,14 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
-    int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB;
-    int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+    int mRoomLevel = -6000;
+    int mRoomHfLevel = 0;
     int mDecayTime = 1000;
     int mDecayHfRatio = 500;
-    int mLevel = EnvironmentalReverb::MIN_LEVEL_MB;
+    int mLevel = -6000;
     int mDelay = 40;
-    int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM;
-    int mDensity = EnvironmentalReverb::MAX_DENSITY_PM;
+    int mDiffusion = 1000;
+    int mDensity = 1000;
     bool mBypass = false;
 
     void SetAndGetReverbParameters() {
@@ -202,11 +178,11 @@
         switch (tag) {
             case EnvironmentalReverb::roomLevelMb: {
                 int roomLevel = er.get<EnvironmentalReverb::roomLevelMb>();
-                return isRoomLevelInRange(roomLevel);
+                return isRoomLevelInRange(erCap, roomLevel);
             }
             case EnvironmentalReverb::roomHfLevelMb: {
                 int roomHfLevel = er.get<EnvironmentalReverb::roomHfLevelMb>();
-                return isRoomHfLevelInRange(roomHfLevel);
+                return isRoomHfLevelInRange(erCap, roomHfLevel);
             }
             case EnvironmentalReverb::decayTimeMs: {
                 int decayTime = er.get<EnvironmentalReverb::decayTimeMs>();
@@ -214,23 +190,23 @@
             }
             case EnvironmentalReverb::decayHfRatioPm: {
                 int decayHfRatio = er.get<EnvironmentalReverb::decayHfRatioPm>();
-                return isDecayHfRatioInRange(decayHfRatio);
+                return isDecayHfRatioInRange(erCap, decayHfRatio);
             }
             case EnvironmentalReverb::levelMb: {
                 int level = er.get<EnvironmentalReverb::levelMb>();
-                return isLevelInRange(level);
+                return isLevelInRange(erCap, level);
             }
             case EnvironmentalReverb::delayMs: {
                 int delay = er.get<EnvironmentalReverb::delayMs>();
-                return isDelayInRange(delay);
+                return isDelayInRange(erCap, delay);
             }
             case EnvironmentalReverb::diffusionPm: {
                 int diffusion = er.get<EnvironmentalReverb::diffusionPm>();
-                return isDiffusionInRange(diffusion);
+                return isDiffusionInRange(erCap, diffusion);
             }
             case EnvironmentalReverb::densityPm: {
                 int density = er.get<EnvironmentalReverb::densityPm>();
-                return isDensityInRange(density);
+                return isDensityInRange(erCap, density);
             }
             case EnvironmentalReverb::bypass: {
                 return true;
@@ -241,45 +217,191 @@
         return false;
     }
 
-    bool isRoomLevelInRange(int roomLevel) const {
-        return roomLevel >= EnvironmentalReverb::MIN_ROOM_LEVEL_MB &&
-               roomLevel <= EnvironmentalReverb::MAX_ROOM_LEVEL_MB;
+    bool isRoomLevelInRange(const EnvironmentalReverb::Capability& cap, int roomLevel) const {
+        return roomLevel >= cap.minRoomLevelMb && roomLevel <= cap.maxRoomLevelMb;
     }
 
-    bool isRoomHfLevelInRange(int roomHfLevel) const {
-        return roomHfLevel >= EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB &&
-               roomHfLevel <= EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+    bool isRoomHfLevelInRange(const EnvironmentalReverb::Capability& cap, int roomHfLevel) const {
+        return roomHfLevel >= cap.minRoomHfLevelMb && roomHfLevel <= cap.maxRoomHfLevelMb;
     }
 
     bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const {
-        return decayTime >= EnvironmentalReverb::MIN_DECAY_TIME_MS &&
-               decayTime <= EnvironmentalReverb::MAX_DECAY_TIME_MS &&
-               decayTime <= cap.maxDecayTimeMs;
+        return decayTime >= 0 && decayTime <= cap.maxDecayTimeMs;
     }
 
-    bool isDecayHfRatioInRange(int decayHfRatio) const {
-        return decayHfRatio >= EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM &&
-               decayHfRatio <= EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM;
+    bool isDecayHfRatioInRange(const EnvironmentalReverb::Capability& cap, int decayHfRatio) const {
+        return decayHfRatio >= cap.minDecayHfRatioPm && decayHfRatio <= cap.maxDecayHfRatioPm;
     }
 
-    bool isLevelInRange(int level) const {
-        return level >= EnvironmentalReverb::MIN_LEVEL_MB &&
-               level <= EnvironmentalReverb::MAX_LEVEL_MB;
+    bool isLevelInRange(const EnvironmentalReverb::Capability& cap, int level) const {
+        return level >= cap.minLevelMb && level <= cap.maxLevelMb;
     }
 
-    bool isDelayInRange(int delay) const {
-        return delay >= EnvironmentalReverb::MIN_DELAY_MS &&
-               delay <= EnvironmentalReverb::MAX_DELAY_MS;
+    bool isDelayInRange(const EnvironmentalReverb::Capability& cap, int delay) const {
+        return delay >= 0 && delay <= cap.maxDelayMs;
     }
 
-    bool isDiffusionInRange(int diffusion) const {
-        return diffusion >= EnvironmentalReverb::MIN_DIFFUSION_PM &&
-               diffusion <= EnvironmentalReverb::MAX_DIFFUSION_PM;
+    bool isDiffusionInRange(const EnvironmentalReverb::Capability& cap, int diffusion) const {
+        return diffusion >= 0 && diffusion <= cap.maxDiffusionPm;
     }
 
-    bool isDensityInRange(int density) const {
-        return density >= EnvironmentalReverb::MIN_DENSITY_PM &&
-               density <= EnvironmentalReverb::MAX_DENSITY_PM;
+    bool isDensityInRange(const EnvironmentalReverb::Capability& cap, int density) const {
+        return density >= 0 && density <= cap.maxDensityPm;
+    }
+
+    static std::unordered_set<int> getRoomLevelValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        int minRoomLevelMb = std::numeric_limits<int>::max();
+        int maxRoomLevelMb = std::numeric_limits<int>::min();
+        for (const auto& it : descList) {
+            maxRoomLevelMb = std::max(
+                    it.second.capability.get<Capability::environmentalReverb>().maxRoomLevelMb,
+                    maxRoomLevelMb);
+            minRoomLevelMb = std::min(
+                    it.second.capability.get<Capability::environmentalReverb>().minRoomLevelMb,
+                    minRoomLevelMb);
+        }
+        return {std::numeric_limits<int>::min(),        minRoomLevelMb - 1, minRoomLevelMb,
+                (minRoomLevelMb + maxRoomLevelMb) >> 1, maxRoomLevelMb,     maxRoomLevelMb + 1,
+                std::numeric_limits<int>::max()};
+    }
+
+    static std::unordered_set<int> getRoomHfLevelValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        int minRoomHfLevelMb = std::numeric_limits<int>::max();
+        int maxRoomHfLevelMb = std::numeric_limits<int>::min();
+        for (const auto& it : descList) {
+            maxRoomHfLevelMb = std::max(
+                    it.second.capability.get<Capability::environmentalReverb>().maxRoomHfLevelMb,
+                    maxRoomHfLevelMb);
+            minRoomHfLevelMb = std::min(
+                    it.second.capability.get<Capability::environmentalReverb>().minRoomHfLevelMb,
+                    minRoomHfLevelMb);
+        }
+        return {std::numeric_limits<int>::min(),
+                minRoomHfLevelMb - 1,
+                minRoomHfLevelMb,
+                (minRoomHfLevelMb + maxRoomHfLevelMb) >> 1,
+                maxRoomHfLevelMb,
+                maxRoomHfLevelMb + 1,
+                std::numeric_limits<int>::max()};
+    }
+
+    static std::unordered_set<int> getDecayTimeValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        const auto max = std::max_element(
+                descList.begin(), descList.end(),
+                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+                    return a.second.capability.get<Capability::environmentalReverb>()
+                                   .maxDecayTimeMs <
+                           b.second.capability.get<Capability::environmentalReverb>()
+                                   .maxDecayTimeMs;
+                });
+        if (max == descList.end()) {
+            return {0};
+        }
+        int maxDecayTimeMs =
+                max->second.capability.get<Capability::environmentalReverb>().maxDecayTimeMs;
+        return {-1, 0, maxDecayTimeMs >> 1, maxDecayTimeMs - 1, maxDecayTimeMs, maxDecayTimeMs + 1};
+    }
+
+    static std::unordered_set<int> getDecayHfRatioValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        int minDecayHfRatioPm = std::numeric_limits<int>::max();
+        int maxDecayHfRatioPm = std::numeric_limits<int>::min();
+        for (const auto& it : descList) {
+            maxDecayHfRatioPm = std::max(
+                    it.second.capability.get<Capability::environmentalReverb>().maxDecayHfRatioPm,
+                    maxDecayHfRatioPm);
+            minDecayHfRatioPm = std::min(
+                    it.second.capability.get<Capability::environmentalReverb>().minDecayHfRatioPm,
+                    minDecayHfRatioPm);
+        }
+        return {std::numeric_limits<int>::min(),
+                minDecayHfRatioPm - 1,
+                minDecayHfRatioPm,
+                (minDecayHfRatioPm + maxDecayHfRatioPm) >> 1,
+                maxDecayHfRatioPm,
+                maxDecayHfRatioPm + 1,
+                std::numeric_limits<int>::max()};
+    }
+
+    static std::unordered_set<int> getLevelValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        int minLevelMb = std::numeric_limits<int>::max();
+        int maxLevelMb = std::numeric_limits<int>::min();
+        for (const auto& it : descList) {
+            maxLevelMb =
+                    std::max(it.second.capability.get<Capability::environmentalReverb>().maxLevelMb,
+                             maxLevelMb);
+            minLevelMb =
+                    std::min(it.second.capability.get<Capability::environmentalReverb>().minLevelMb,
+                             minLevelMb);
+        }
+        return {std::numeric_limits<int>::min(), minLevelMb - 1, minLevelMb,
+                (minLevelMb + maxLevelMb) >> 1,  maxLevelMb,     maxLevelMb + 1,
+                std::numeric_limits<int>::max()};
+    }
+
+    static std::unordered_set<int> getDelayValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        const auto max = std::max_element(
+                descList.begin(), descList.end(),
+                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+                    return a.second.capability.get<Capability::environmentalReverb>().maxDelayMs <
+                           b.second.capability.get<Capability::environmentalReverb>().maxDelayMs;
+                });
+        if (max == descList.end()) {
+            return {0};
+        }
+        int maxDelayMs = max->second.capability.get<Capability::environmentalReverb>().maxDelayMs;
+        return {-1, 0, maxDelayMs >> 1, maxDelayMs - 1, maxDelayMs, maxDelayMs + 1};
+    }
+
+    static std::unordered_set<int> getDiffusionValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        const auto max = std::max_element(
+                descList.begin(), descList.end(),
+                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+                    return a.second.capability.get<Capability::environmentalReverb>()
+                                   .maxDiffusionPm <
+                           b.second.capability.get<Capability::environmentalReverb>()
+                                   .maxDiffusionPm;
+                });
+        if (max == descList.end()) {
+            return {0};
+        }
+        int maxDiffusionPm =
+                max->second.capability.get<Capability::environmentalReverb>().maxDiffusionPm;
+        return {-1, 0, maxDiffusionPm >> 1, maxDiffusionPm - 1, maxDiffusionPm, maxDiffusionPm + 1};
+    }
+
+    static std::unordered_set<int> getDensityValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kEnvReverbTypeUUID);
+        const auto max = std::max_element(
+                descList.begin(), descList.end(),
+                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+                    return a.second.capability.get<Capability::environmentalReverb>().maxDensityPm <
+                           b.second.capability.get<Capability::environmentalReverb>().maxDensityPm;
+                });
+        if (max == descList.end()) {
+            return {0};
+        }
+        int maxDensityPm =
+                max->second.capability.get<Capability::environmentalReverb>().maxDensityPm;
+        return {-1, 0, maxDensityPm >> 1, maxDensityPm - 1, maxDensityPm, maxDensityPm + 1};
     }
 
   private:
@@ -310,7 +432,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kRoomLevelValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getRoomLevelValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string roomLevel = std::to_string(std::get<1>(info.param));
@@ -347,7 +469,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kRoomHfLevelValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getRoomHfLevelValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string roomHfLevel = std::to_string(std::get<1>(info.param));
@@ -384,7 +506,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kDecayTimeValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getDecayTimeValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string decayTime = std::to_string(std::get<1>(info.param));
@@ -421,7 +543,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kDecayHfRatioValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getDecayHfRatioValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string decayHfRatio = std::to_string(std::get<1>(info.param));
@@ -459,7 +581,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kLevelValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getLevelValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string level = std::to_string(std::get<1>(info.param));
@@ -496,7 +618,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kDelayValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getDelayValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string delay = std::to_string(std::get<1>(info.param));
@@ -533,7 +655,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kDiffusionValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getDiffusionValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string diffusion = std::to_string(std::get<1>(info.param));
@@ -570,7 +692,7 @@
         EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(kDensityValues)),
+                           testing::ValuesIn(EnvironmentalReverbHelper::getDensityValues())),
         [](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string density = std::to_string(std::get<1>(info.param));
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index d828cee..3741a64 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -17,7 +17,10 @@
 #ifndef HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
 #define HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
 
+// TODO: LOG_TAG should not be in header
+#ifndef LOG_TAG
 #define LOG_TAG "camera_aidl_hal_test"
+#endif
 
 #include <string>
 #include <unordered_map>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index c665799..90bbfb3 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -1,12 +1,4 @@
 <compatibility-matrix version="1.0" type="framework" level="8">
-    <hal format="hidl" optional="true">
-        <name>android.hardware.atrace</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAtraceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.audio</name>
         <version>6.0</version>
@@ -277,14 +269,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.gatekeeper</name>
-        <version>1.0</version>
-        <interface>
-            <name>IGatekeeper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.gatekeeper</name>
         <version>1</version>
@@ -717,23 +701,26 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.tv.cec</name>
+        <name>android.hardware.tv.hdmi.cec</name>
+        <version>1</version>
         <interface>
             <name>IHdmiCec</name>
             <instance>default</instance>
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.tv.earc</name>
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
         <interface>
             <name>IEArc</name>
             <instance>default</instance>
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.tv.hdmi</name>
+        <name>android.hardware.tv.hdmi.connection</name>
+        <version>1</version>
         <interface>
-            <name>IHdmi</name>
+            <name>IHdmiConnection</name>
             <instance>default</instance>
         </interface>
     </hal>
@@ -777,6 +764,13 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
diff --git a/drm/aidl/vts/drm_hal_test.cpp b/drm/aidl/vts/drm_hal_test.cpp
index 14b3acf..847a4dc 100644
--- a/drm/aidl/vts/drm_hal_test.cpp
+++ b/drm/aidl/vts/drm_hal_test.cpp
@@ -198,6 +198,18 @@
         EXPECT_NE(keySetId, keySetId2.keySetId);
     }
 
+    for (auto level : {kHwSecureAll, kSwSecureCrypto}) {
+        Status err = Status::OK;
+        auto sid = openSession(level, &err);
+        if (err == Status::OK) {
+            closeSession(sid);
+        } else if (err == Status::ERROR_DRM_CANNOT_HANDLE) {
+            continue;
+        } else {
+            EXPECT_EQ(Status::ERROR_DRM_NOT_PROVISIONED, err);
+            provision();
+        }
+    }
     ret = drmPlugin->removeOfflineLicense({keySetId});
     EXPECT_TXN(ret);
     EXPECT_EQ(Status::BAD_VALUE, DrmErr(ret));
diff --git a/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl b/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl
index 927293e..215c6e6 100644
--- a/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl
+++ b/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl
@@ -30,7 +30,7 @@
     const int STATUS_REENROLL = 1;
     /* operation is successful */
     const int STATUS_OK = 0;
-    /* operation is successful. */
+    /* operation failed. */
     const int ERROR_GENERAL_FAILURE = -1;
     /* operation should  be retried after timeout. */
     const int ERROR_RETRY_TIMEOUT = -2;
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
index 6e7b739..e50d170 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
@@ -34,7 +34,7 @@
 package android.hardware.graphics.allocator;
 @Backing(type="int") @VintfStability
 enum AllocationError {
-  BAD_DESCRIPTOR = 0,
-  NO_RESOURCES = 1,
-  UNSUPPORTED = 2,
+  BAD_DESCRIPTOR,
+  NO_RESOURCES,
+  UNSUPPORTED,
 }
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
index 48bef16..66e49a7 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 interface IAllocator {
   /**
-   * @deprecated As of android.hardware.graphics.allocator-V2, this is deprecated & replaced with allocate2
+   * @deprecated As of android.hardware.graphics.allocator-V2 in combination with AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2. If android.hardware.graphics.mapper@4 is still in use, however, this is still required to be implemented.
    */
   android.hardware.graphics.allocator.AllocationResult allocate(in byte[] descriptor, in int count);
   android.hardware.graphics.allocator.AllocationResult allocate2(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor, in int count);
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
index 71cebd6..2277bae 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
@@ -32,8 +32,10 @@
      * @param count The number of buffers to allocate.
      * @return An AllocationResult containing the result of the allocation
      * @throws AllocationError on failure
-     * @deprecated As of android.hardware.graphics.allocator-V2, this is deprecated & replaced with
-     *         allocate2
+     * @deprecated As of android.hardware.graphics.allocator-V2 in combination with
+     *             AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2.
+     *             If android.hardware.graphics.mapper@4 is still in use, however, this is
+     *             still required to be implemented.
      */
     AllocationResult allocate(in byte[] descriptor, in int count);
 
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
index 0f6d146..0de88cd 100644
--- a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -241,7 +241,9 @@
      * acceptable.
      *
      * 1D buffers (width = size in bytes, height = 1, pixel_format = BLOB) must
-     * "lock in place". The buffers must be directly accessible via mapping.
+     * "lock in place" and behave similar to shared memory. That is, multiple threads or processes
+     * may lock the buffer for reading & writing and the results must follow the device's memory
+     * model.
      *
      * The client must not modify the content of the buffer outside of
      * @p accessRegion, and the device need not guarantee that content outside
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index a4d4ace..64d83f3 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -46,8 +46,8 @@
 
 }
 
-cc_library {
-    name: "android.hardware.health-translate-ndk",
+cc_defaults {
+    name: "android.hardware.health-translate-ndk_defaults",
     vendor_available: true,
     recovery_available: true,
     host_supported: true,
@@ -55,7 +55,6 @@
     shared_libs: [
         "libbinder_ndk",
         "libhidlbase",
-        "android.hardware.health-V1-ndk",
         "android.hardware.health@2.0",
         "android.hardware.health@2.1",
     ],
@@ -71,6 +70,23 @@
     },
 }
 
+cc_library {
+    name: "android.hardware.health-translate-ndk",
+    defaults: ["android.hardware.health-translate-ndk_defaults"],
+    shared_libs: [
+        "android.hardware.health-V1-ndk",
+    ],
+}
+
+// TODO(b/251425963): remove when android.hardware.health is upgraded to V2.
+cc_library {
+    name: "android.hardware.health-translate-V1-ndk",
+    defaults: ["android.hardware.health-translate-ndk_defaults"],
+    shared_libs: [
+        "android.hardware.health-V1-ndk",
+    ],
+}
+
 java_library {
     name: "android.hardware.health-translate-java",
     srcs: ["android/hardware/health/Translate.java"],
diff --git a/scripts/anapic_hidl2aidl_review.sh b/scripts/anapic_hidl2aidl_review.sh
new file mode 100755
index 0000000..330ae32
--- /dev/null
+++ b/scripts/anapic_hidl2aidl_review.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [[ $# -ne 1 ]]; then
+    echo "Usage: $0 INTERFACE_NAME"
+    echo "- INTERFACE_NAME fully qualified HIDL interface name with version"
+    echo "example of creating the diffs for android.hardware.boot@1.2"
+    echo "$ ./anapic_hidl2aidl_review.sh android.hardware.boot@1.2"
+    exit 1
+fi
+
+# for pathmod
+source ${ANDROID_BUILD_TOP}/build/make/envsetup.sh
+
+set -ex
+type hidl2aidl 2>/dev/null || m hidl2aidl
+
+INTERFACE_NAME_NO_VER=${1%@*}
+pushd $(pathmod $INTERFACE_NAME_NO_VER)
+rm -rf android
+hidl2aidl -o . "$1"
+rm -rf conversion.log translate include
+git add -A
+git commit -am "convert $1" --no-edit
+git revert HEAD --no-edit
+git commit --amend --no-edit
+repo upload . --no-verify
+popd
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 88badc7..58b0645 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -31,8 +31,10 @@
         "VtsHalTargetTestDefaults",
     ],
     shared_libs: [
+        "libbinder",
         "libbinder_ndk",
         "libcrypto",
+        "packagemanager_aidl-cpp",
     ],
     static_libs: [
         "android.hardware.security.rkp-V3-ndk",
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 6c012fa..e9cbe10 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -23,6 +23,7 @@
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
+#include <android/content/pm/IPackageManagerNative.h>
 #include <cppbor_parse.h>
 #include <cutils/properties.h>
 #include <gmock/gmock.h>
@@ -2048,6 +2049,29 @@
     }
 }
 
+// Check whether the given named feature is available.
+bool check_feature(const std::string& name) {
+    ::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager());
+    ::android::sp<::android::IBinder> binder(sm->getService(::android::String16("package_native")));
+    if (binder == nullptr) {
+        GTEST_LOG_(ERROR) << "getService package_native failed";
+        return false;
+    }
+    ::android::sp<::android::content::pm::IPackageManagerNative> packageMgr =
+            ::android::interface_cast<::android::content::pm::IPackageManagerNative>(binder);
+    if (packageMgr == nullptr) {
+        GTEST_LOG_(ERROR) << "Cannot find package manager";
+        return false;
+    }
+    bool hasFeature = false;
+    auto status = packageMgr->hasSystemFeature(::android::String16(name.c_str()), 0, &hasFeature);
+    if (!status.isOk()) {
+        GTEST_LOG_(ERROR) << "hasSystemFeature('" << name << "') failed: " << status;
+        return false;
+    }
+    return hasFeature;
+}
+
 }  // namespace test
 
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 908eeab..fae9459 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -402,6 +402,7 @@
                         vector<uint8_t>* payload_value);
 void p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
 void device_id_attestation_vsr_check(const ErrorCode& result);
+bool check_feature(const std::string& name);
 
 AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
 AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
diff --git a/tv/cec/aidl/Android.bp b/tv/cec/aidl/Android.bp
deleted file mode 100644
index 0b0e7cf..0000000
--- a/tv/cec/aidl/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-aidl_interface {
-    name: "android.hardware.tv.cec",
-    vendor_available: true,
-    srcs: ["android/hardware/tv/cec/*.aidl"],
-    stability: "vintf",
-    backend: {
-        java: {
-            sdk_version: "module_current",
-        },
-    },
-}
diff --git a/tv/cec/aidl/OWNERS b/tv/cec/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/cec/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/cec/aidl/TEST_MAPPING b/tv/cec/aidl/TEST_MAPPING
deleted file mode 100644
index ef4bee1..0000000
--- a/tv/cec/aidl/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "VtsHalTvCecAidlTargetTest"
-    }
-  ]
-}
diff --git a/tv/cec/aidl/default/android.hardware.tv.cec-service.rc b/tv/cec/aidl/default/android.hardware.tv.cec-service.rc
deleted file mode 100644
index c79520c..0000000
--- a/tv/cec/aidl/default/android.hardware.tv.cec-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.cec-default /vendor/bin/hw/android.hardware.tv.cec-service
-    interface aidl android.hardware.tv.cec.IHdmiCec/default
-    class hal
-    user system
-    group system
diff --git a/tv/cec/aidl/vts/functional/Android.bp b/tv/cec/aidl/vts/functional/Android.bp
deleted file mode 100644
index 37fbaf0..0000000
--- a/tv/cec/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_test {
-    name: "VtsHalTvCecAidlTargetTest",
-    defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
-    ],
-    srcs: ["VtsHalTvCecAidlTargetTest.cpp"],
-    static_libs: [
-        "android.hardware.tv.cec-V1-ndk",
-        "android.hardware.tv.hdmi-V1-ndk",
-    ],
-    shared_libs: [
-        "libbinder_ndk",
-    ],
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-    disable_framework: true,
-}
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.rc b/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
deleted file mode 100644
index 0d9063e..0000000
--- a/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-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/hdmi/aidl/default/Android.bp b/tv/hdmi/aidl/default/Android.bp
deleted file mode 100644
index 3e466a0..0000000
--- a/tv/hdmi/aidl/default/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_binary {
-    name: "android.hardware.tv.hdmi-service",
-    vintf_fragments: ["android.hardware.tv.hdmi-service.xml"],
-    relative_install_path: "hw",
-    vendor: true,
-    cflags: [
-        "-Wall",
-        "-Wextra",
-    ],
-    init_rc: ["android.hardware.tv.hdmi-service.rc"],
-    srcs: [
-        "serviceMock.cpp",
-        "HdmiMock.cpp",
-    ],
-    shared_libs: [
-        "libbinder_ndk",
-        "liblog",
-        "libbase",
-        "libutils",
-        "libhardware",
-        "libhidlbase",
-        "android.hardware.tv.hdmi-V1-ndk",
-    ],
-}
-
-cc_fuzz {
-    name: "android.hardware.tv.hdmi-service_fuzzer",
-    defaults: ["service_fuzzer_defaults"],
-    static_libs: [
-        "android.hardware.tv.hdmi-V1-ndk",
-        "liblog",
-    ],
-    srcs: [
-        "fuzzer.cpp",
-        "HdmiMock.cpp",
-    ],
-    fuzz_config: {
-        componentid: 826094,
-    },
-}
diff --git a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc b/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc
deleted file mode 100644
index c926221..0000000
--- a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi-service
-    interface aidl android.hardware.tv.hdmi.IHdmi/default
-    class hal
-    user system
-    group system
diff --git a/tv/hdmi/aidl/vts/functional/Android.bp b/tv/hdmi/aidl/vts/functional/Android.bp
deleted file mode 100644
index f9af58d..0000000
--- a/tv/hdmi/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_test {
-    name: "VtsHalTvHdmiAidlTargetTest",
-    defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
-    ],
-    srcs: ["VtsHalTvHdmiAidlTargetTest.cpp"],
-    static_libs: [
-        "android.hardware.tv.hdmi-V1-ndk",
-    ],
-    shared_libs: [
-        "libbinder_ndk",
-    ],
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-    disable_framework: true,
-}
diff --git a/tv/hdmi/aidl/Android.bp b/tv/hdmi/cec/aidl/Android.bp
similarity index 90%
rename from tv/hdmi/aidl/Android.bp
rename to tv/hdmi/cec/aidl/Android.bp
index d8c6e5f..1bd9e41 100644
--- a/tv/hdmi/aidl/Android.bp
+++ b/tv/hdmi/cec/aidl/Android.bp
@@ -17,9 +17,9 @@
 }
 
 aidl_interface {
-    name: "android.hardware.tv.hdmi",
+    name: "android.hardware.tv.hdmi.cec",
     vendor_available: true,
-    srcs: ["android/hardware/tv/hdmi/*.aidl"],
+    srcs: ["android/hardware/tv/hdmi/cec/*.aidl"],
     stability: "vintf",
     backend: {
         java: {
diff --git a/tv/hdmi/aidl/OWNERS b/tv/hdmi/cec/aidl/OWNERS
similarity index 100%
rename from tv/hdmi/aidl/OWNERS
rename to tv/hdmi/cec/aidl/OWNERS
diff --git a/tv/hdmi/cec/aidl/TEST_MAPPING b/tv/hdmi/cec/aidl/TEST_MAPPING
new file mode 100644
index 0000000..17d6bca
--- /dev/null
+++ b/tv/hdmi/cec/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvHdmiCecAidlTargetTest"
+    }
+  ]
+}
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
index 7377d81..45b973a 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="int") @VintfStability
 enum AbortReason {
   UNRECOGNIZED_MODE = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
index 4d991cd..08dc1ee 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="byte") @VintfStability
 enum CecDeviceType {
   INACTIVE = -1,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
index a36935b..1fc9fb7 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="byte") @VintfStability
 enum CecLogicalAddress {
   TV = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
similarity index 91%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
index 5ce5ce8..9de07ec 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -31,11 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @VintfStability
 parcelable CecMessage {
-  android.hardware.tv.cec.CecLogicalAddress initiator;
-  android.hardware.tv.cec.CecLogicalAddress destination;
+  android.hardware.tv.hdmi.cec.CecLogicalAddress initiator;
+  android.hardware.tv.hdmi.cec.CecLogicalAddress destination;
   byte[] body;
   const int MAX_MESSAGE_BODY_LENGTH = 15;
 }
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
similarity index 98%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
index 61ebb94..31ca895 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="int") @VintfStability
 enum CecMessageType {
   FEATURE_ABORT = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
similarity index 85%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index cf8425e..0881489 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -31,17 +31,17 @@
 // 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.cec;
+package android.hardware.tv.hdmi.cec;
 @VintfStability
 interface IHdmiCec {
-  android.hardware.tv.cec.Result addLogicalAddress(in android.hardware.tv.cec.CecLogicalAddress addr);
+  android.hardware.tv.hdmi.cec.Result addLogicalAddress(in android.hardware.tv.hdmi.cec.CecLogicalAddress addr);
   void clearLogicalAddress();
   void enableAudioReturnChannel(in int portId, in boolean enable);
   int getCecVersion();
   int getPhysicalAddress();
   int getVendorId();
-  android.hardware.tv.cec.SendMessageResult sendMessage(in android.hardware.tv.cec.CecMessage message);
-  void setCallback(in android.hardware.tv.cec.IHdmiCecCallback callback);
+  android.hardware.tv.hdmi.cec.SendMessageResult sendMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+  void setCallback(in android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
   void setLanguage(in String language);
   void enableWakeupByOtp(in boolean value);
   void enableCec(in boolean value);
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
similarity index 93%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
index 1918765..43fdfbd 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -31,8 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @VintfStability
 interface IHdmiCecCallback {
-  oneway void onCecMessage(in android.hardware.tv.cec.CecMessage message);
+  oneway void onCecMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
 }
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
index a5ba276..c6828ef 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="byte") @VintfStability
 enum Result {
   SUCCESS = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
index 58206c8..87b50c9 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 @Backing(type="byte") @VintfStability
 enum SendMessageResult {
   SUCCESS = 0,
diff --git a/tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
index 3ae23ec..297094d 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 /**
  * Operand description [Abort Reason]
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
index 16dfbec..8727a1d 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 @VintfStability
 @Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
index fbf5328..e7e08a6 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 @VintfStability
 @Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
similarity index 92%
rename from tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
index b126045..14a1bc7 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
-import android.hardware.tv.cec.CecLogicalAddress;
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
 
 @VintfStability
 parcelable CecMessage {
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
similarity index 98%
rename from tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
index b544a91..becfea1 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 @VintfStability
 @Backing(type="int")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index dbf7139..577c377 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
-import android.hardware.tv.cec.CecLogicalAddress;
-import android.hardware.tv.cec.CecMessage;
-import android.hardware.tv.cec.IHdmiCecCallback;
-import android.hardware.tv.cec.Result;
-import android.hardware.tv.cec.SendMessageResult;
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
+import android.hardware.tv.hdmi.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.IHdmiCecCallback;
+import android.hardware.tv.hdmi.cec.Result;
+import android.hardware.tv.hdmi.cec.SendMessageResult;
 
 /**
  * HDMI-CEC HAL interface definition.
diff --git a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
similarity index 91%
rename from tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
index 4934a64..ef73dd7 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
-import android.hardware.tv.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.CecMessage;
 
 /**
  * Callbacks from the HAL implementation to notify the system of new events.
diff --git a/tv/cec/aidl/android/hardware/tv/cec/Result.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/Result.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
index 3184c46..1b1cd08 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/Result.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 @VintfStability
 @Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
index 8cb98bc..8f609d5 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
 
 /**
  * error code used for send_message.
diff --git a/tv/cec/aidl/default/Android.bp b/tv/hdmi/cec/aidl/default/Android.bp
similarity index 79%
rename from tv/cec/aidl/default/Android.bp
rename to tv/hdmi/cec/aidl/default/Android.bp
index 5479601..ea4bb94 100644
--- a/tv/cec/aidl/default/Android.bp
+++ b/tv/hdmi/cec/aidl/default/Android.bp
@@ -17,15 +17,15 @@
 }
 
 cc_binary {
-    name: "android.hardware.tv.cec-service",
-    vintf_fragments: ["android.hardware.tv.cec-service.xml"],
+    name: "android.hardware.tv.hdmi.cec-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.cec-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     cflags: [
         "-Wall",
         "-Wextra",
     ],
-    init_rc: ["android.hardware.tv.cec-service.rc"],
+    init_rc: ["android.hardware.tv.hdmi.cec-service.rc"],
     srcs: [
         "serviceMock.cpp",
         "HdmiCecMock.cpp",
@@ -37,15 +37,15 @@
         "libutils",
         "libhardware",
         "libhidlbase",
-        "android.hardware.tv.cec-V1-ndk",
+        "android.hardware.tv.hdmi.cec-V1-ndk",
     ],
 }
 
 cc_fuzz {
-    name: "android.hardware.tv.cec-service_fuzzer",
+    name: "android.hardware.tv.hdmi.cec-service_fuzzer",
     defaults: ["service_fuzzer_defaults"],
     static_libs: [
-        "android.hardware.tv.cec-V1-ndk",
+        "android.hardware.tv.hdmi.cec-V1-ndk",
         "liblog",
     ],
     srcs: [
diff --git a/tv/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
similarity index 98%
rename from tv/cec/aidl/default/HdmiCecMock.cpp
rename to tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index d8d655b..0212e7e 100644
--- a/tv/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.cec"
+#define LOG_TAG "android.hardware.tv.hdmi.cec"
 #include <android-base/logging.h>
 #include <fcntl.h>
 #include <utils/Log.h>
@@ -28,6 +28,7 @@
 namespace android {
 namespace hardware {
 namespace tv {
+namespace hdmi {
 namespace cec {
 namespace implementation {
 
@@ -261,6 +262,7 @@
 
 }  // namespace implementation
 }  // namespace cec
+}  // namespace hdmi
 }  // namespace tv
 }  // namespace hardware
 }  // namespace android
diff --git a/tv/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
similarity index 85%
rename from tv/cec/aidl/default/HdmiCecMock.h
rename to tv/hdmi/cec/aidl/default/HdmiCecMock.h
index 08f4d6f..aca0581 100644
--- a/tv/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
 #include <algorithm>
 #include <vector>
 
@@ -23,16 +23,17 @@
 namespace android {
 namespace hardware {
 namespace tv {
+namespace hdmi {
 namespace cec {
 namespace implementation {
 
-using ::aidl::android::hardware::tv::cec::BnHdmiCec;
-using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
-using ::aidl::android::hardware::tv::cec::CecMessage;
-using ::aidl::android::hardware::tv::cec::IHdmiCec;
-using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::Result;
-using ::aidl::android::hardware::tv::cec::SendMessageResult;
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
 
 #define CEC_MSG_IN_FIFO "/dev/cec_aidl_in_pipe"
 #define CEC_MSG_OUT_FIFO "/dev/cec_aidl_out_pipe"
@@ -89,6 +90,7 @@
 };
 }  // namespace implementation
 }  // namespace cec
+}  // namespace hdmi
 }  // namespace tv
 }  // namespace hardware
 }  // namespace android
diff --git a/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
new file mode 100644
index 0000000..f4c9fcf
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
@@ -0,0 +1,5 @@
+service vendor.cec-default /vendor/bin/hw/android.hardware.tv.hdmi.cec-service
+    interface aidl android.hardware.tv.hdmi.cec.IHdmiCec/default
+    class hal
+    user system
+    group system
diff --git a/tv/cec/aidl/default/android.hardware.tv.cec-service.xml b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
similarity index 81%
rename from tv/cec/aidl/default/android.hardware.tv.cec-service.xml
rename to tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
index e68450d..d48565c 100644
--- a/tv/cec/aidl/default/android.hardware.tv.cec-service.xml
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
@@ -1,6 +1,6 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
-        <name>android.hardware.tv.cec</name>
+        <name>android.hardware.tv.hdmi.cec</name>
         <version>1</version>
         <interface>
             <name>IHdmiCec</name>
diff --git a/tv/cec/aidl/default/fuzzer.cpp b/tv/hdmi/cec/aidl/default/fuzzer.cpp
similarity index 93%
rename from tv/cec/aidl/default/fuzzer.cpp
rename to tv/hdmi/cec/aidl/default/fuzzer.cpp
index 9f6a9ac..33453dc 100644
--- a/tv/cec/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/cec/aidl/default/fuzzer.cpp
@@ -18,7 +18,7 @@
 #include <fuzzer/FuzzedDataProvider.h>
 
 using android::fuzzService;
-using android::hardware::tv::cec::implementation::HdmiCecMock;
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
 using ndk::SharedRefBase;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/tv/cec/aidl/default/serviceMock.cpp b/tv/hdmi/cec/aidl/default/serviceMock.cpp
similarity index 90%
rename from tv/cec/aidl/default/serviceMock.cpp
rename to tv/hdmi/cec/aidl/default/serviceMock.cpp
index ab86c3f..cbf85e5 100644
--- a/tv/cec/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/cec/aidl/default/serviceMock.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.cec-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.cec-service-shim"
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
@@ -23,7 +23,7 @@
 #include <utils/Log.h>
 #include "HdmiCecMock.h"
 
-using android::hardware::tv::cec::implementation::HdmiCecMock;
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
 
 int main() {
     ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/cec/aidl/vts/functional/Android.bp
similarity index 83%
copy from tv/earc/aidl/vts/functional/Android.bp
copy to tv/hdmi/cec/aidl/vts/functional/Android.bp
index 797547e..5c86d3f 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/cec/aidl/vts/functional/Android.bp
@@ -17,14 +17,15 @@
 }
 
 cc_test {
-    name: "VtsHalTvEArcAidlTargetTest",
+    name: "VtsHalTvHdmiCecAidlTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
-    srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+    srcs: ["VtsHalTvHdmiCecAidlTargetTest.cpp"],
     static_libs: [
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.cec-V1-ndk",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/tv/cec/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
similarity index 82%
rename from tv/cec/aidl/vts/functional/AndroidTest.xml
rename to tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
index 8604147..63e7763 100644
--- a/tv/cec/aidl/vts/functional/AndroidTest.xml
+++ b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs VtsHalTvCecAidlTargetTest.">
+<configuration description="Runs VtsHalTvHdmiCecAidlTargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
 
@@ -22,12 +22,12 @@
 
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
-        <option name="push" value="VtsHalTvCecAidlTargetTest->/data/local/tmp/VtsHalTvCecAidlTargetTest" />
+        <option name="push" value="VtsHalTvHdmiCecAidlTargetTest->/data/local/tmp/VtsHalTvHdmiCecAidlTargetTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="VtsHalTvCecAidlTargetTest" />
+        <option name="module-name" value="VtsHalTvHdmiCecAidlTargetTest" />
         <option name="native-test-timeout" value="30m" />
     </test>
 </configuration>
diff --git a/tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
similarity index 86%
rename from tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp
rename to tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
index 69c209f..a2fb0f8 100644
--- a/tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp
+++ b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
@@ -18,10 +18,10 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
-#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
-#include <aidl/android/hardware/tv/cec/BnHdmiCecCallback.h>
-#include <aidl/android/hardware/tv/cec/CecDeviceType.h>
-#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCecCallback.h>
+#include <aidl/android/hardware/tv/hdmi/cec/CecDeviceType.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -30,15 +30,15 @@
 #include <sstream>
 #include <vector>
 
-using ::aidl::android::hardware::tv::cec::BnHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::CecDeviceType;
-using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
-using ::aidl::android::hardware::tv::cec::CecMessage;
-using ::aidl::android::hardware::tv::cec::IHdmiCec;
-using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::Result;
-using ::aidl::android::hardware::tv::cec::SendMessageResult;
-using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::CecDeviceType;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
 using ::ndk::SpAIBinder;
 
 #define CEC_VERSION 0x05
diff --git a/tv/earc/aidl/Android.bp b/tv/hdmi/connection/aidl/Android.bp
similarity index 88%
rename from tv/earc/aidl/Android.bp
rename to tv/hdmi/connection/aidl/Android.bp
index 5db6032..b342c52 100644
--- a/tv/earc/aidl/Android.bp
+++ b/tv/hdmi/connection/aidl/Android.bp
@@ -17,9 +17,9 @@
 }
 
 aidl_interface {
-    name: "android.hardware.tv.earc",
+    name: "android.hardware.tv.hdmi.connection",
     vendor_available: true,
-    srcs: ["android/hardware/tv/earc/*.aidl"],
+    srcs: ["android/hardware/tv/hdmi/connection/*.aidl"],
     stability: "vintf",
     backend: {
         java: {
diff --git a/tv/hdmi/aidl/OWNERS b/tv/hdmi/connection/aidl/OWNERS
similarity index 100%
copy from tv/hdmi/aidl/OWNERS
copy to tv/hdmi/connection/aidl/OWNERS
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
similarity index 94%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
index 25c3be1..ac35c99 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -31,10 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @VintfStability
 parcelable HdmiPortInfo {
-  android.hardware.tv.hdmi.HdmiPortType type;
+  android.hardware.tv.hdmi.connection.HdmiPortType type;
   int portId;
   boolean cecSupported;
   boolean arcSupported;
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
index af5f0f7..fc2d7e5 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @Backing(type="byte") @VintfStability
 enum HdmiPortType {
   INPUT = 0,
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
index eef4025..697da29 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @Backing(type="byte") @VintfStability
 enum HpdSignal {
   HDMI_HPD_PHYSICAL = 0,
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
similarity index 81%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index 809d392..98d1452 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -31,12 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @VintfStability
-interface IHdmi {
-  android.hardware.tv.hdmi.HdmiPortInfo[] getPortInfo();
+interface IHdmiConnection {
+  android.hardware.tv.hdmi.connection.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();
+  void setCallback(in android.hardware.tv.hdmi.connection.IHdmiConnectionCallback callback);
+  void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal);
+  android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal();
 }
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
similarity index 94%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
index 05fe623..f9f6856 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -31,8 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @VintfStability
-interface IHdmiCallback {
+interface IHdmiConnectionCallback {
   oneway void onHotplugEvent(in boolean connected, in int portId);
 }
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
index b6b0eb3..93182c5 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 @VintfStability
 enum Result {
   SUCCESS = 0,
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
similarity index 90%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
index 2e2c858..c8a10d1 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
-import android.hardware.tv.hdmi.HdmiPortType;
+import android.hardware.tv.hdmi.connection.HdmiPortType;
 
 /**
  * HDMI port descriptor
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
similarity index 93%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
index 59c0d42..4ec58ee 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
 /**
  * HDMI port type.
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
similarity index 94%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
index 05963f2..554dcf6 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
 /**
  * HPD (Hotplug Detection) Signal Types
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
similarity index 71%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index 457234d..c8759f2 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
-import android.hardware.tv.hdmi.HdmiPortInfo;
-import android.hardware.tv.hdmi.HpdSignal;
-import android.hardware.tv.hdmi.IHdmiCallback;
+import android.hardware.tv.hdmi.connection.HdmiPortInfo;
+import android.hardware.tv.hdmi.connection.HpdSignal;
+import android.hardware.tv.hdmi.connection.IHdmiConnectionCallback;
 
 /**
- * HDMI HAL interface definition.
+ * HDMI Connection HAL interface definition.
  */
 @VintfStability
-interface IHdmi {
+interface IHdmiConnection {
     /**
      * Gets the hdmi port information of underlying hardware.
      *
@@ -48,13 +48,18 @@
      *        previously registered callback must be replaced with this one.
      *        setCallback(null) should deregister the callback.
      */
-    void setCallback(in IHdmiCallback callback);
+    void setCallback(in IHdmiConnectionCallback 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.
+     * @throws ServiceSpecificException with error code set to
+     *         {@code Result::FAILURE_NOT_SUPPORTED} if the signal type is not supported.
+     *         {@code Result::FAILURE_INVALID_ARGS} if the signal type is invalid.
+     *         {@code Result::FAILURE_UNKNOWN} if the signal type could not be set because of an
+     *                                         unknown failure.
      */
     void setHpdSignal(HpdSignal signal);
 
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
similarity index 90%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
index 51275b0..8b001fb 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
 /**
  * Callbacks from the HDMI HAL implementation to notify the system of new events.
  */
 @VintfStability
-oneway interface IHdmiCallback {
+oneway interface IHdmiConnectionCallback {
     /**
      * The callback function that must be called by HAL implementation to notify
      * the system of new hotplug event.
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
similarity index 96%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
index d2a1fef..edaa0a0 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
 
 /**
  * Result enum for return values. Used by the HDMI related AIDL.
diff --git a/tv/earc/aidl/default/Android.bp b/tv/hdmi/connection/aidl/default/Android.bp
similarity index 73%
copy from tv/earc/aidl/default/Android.bp
copy to tv/hdmi/connection/aidl/default/Android.bp
index 399f029..5e7e330 100644
--- a/tv/earc/aidl/default/Android.bp
+++ b/tv/hdmi/connection/aidl/default/Android.bp
@@ -17,18 +17,18 @@
 }
 
 cc_binary {
-    name: "android.hardware.tv.earc-service",
-    vintf_fragments: ["android.hardware.tv.earc-service.xml"],
+    name: "android.hardware.tv.hdmi.connection-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.connection-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     cflags: [
         "-Wall",
         "-Wextra",
     ],
-    init_rc: ["android.hardware.tv.earc-service.rc"],
+    init_rc: ["android.hardware.tv.hdmi.connection-service.rc"],
     srcs: [
         "serviceMock.cpp",
-        "EArcMock.cpp",
+        "HdmiConnectionMock.cpp",
     ],
     shared_libs: [
         "libbinder_ndk",
@@ -37,20 +37,20 @@
         "libutils",
         "libhardware",
         "libhidlbase",
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
     ],
 }
 
 cc_fuzz {
-    name: "android.hardware.tv.earc-service_fuzzer",
+    name: "android.hardware.tv.hdmi.connection-service_fuzzer",
     defaults: ["service_fuzzer_defaults"],
     static_libs: [
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
         "liblog",
     ],
     srcs: [
         "fuzzer.cpp",
-        "EArcMock.cpp",
+        "HdmiConnectionMock.cpp",
     ],
     fuzz_config: {
         componentid: 826094,
diff --git a/tv/hdmi/aidl/default/HdmiMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
similarity index 81%
rename from tv/hdmi/aidl/default/HdmiMock.cpp
rename to tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index 7cd9bb7..db9f4c1 100644
--- a/tv/hdmi/aidl/default/HdmiMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.hdmi"
+#define LOG_TAG "android.hardware.tv.hdmi.connection"
 #include <android-base/logging.h>
 #include <fcntl.h>
 #include <utils/Log.h>
 
-#include "HdmiMock.h"
+#include "HdmiConnectionMock.h"
 
 using ndk::ScopedAStatus;
 
@@ -27,20 +27,21 @@
 namespace hardware {
 namespace tv {
 namespace hdmi {
+namespace connection {
 namespace implementation {
 
-void HdmiMock::serviceDied(void* cookie) {
-    ALOGE("HdmiMock died");
-    auto hdmi = static_cast<HdmiMock*>(cookie);
+void HdmiConnectionMock::serviceDied(void* cookie) {
+    ALOGE("HdmiConnectionMock died");
+    auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
     hdmi->mHdmiThreadRun = false;
 }
 
-ScopedAStatus HdmiMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
     *_aidl_return = mPortInfos;
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus HdmiMock::isConnected(int32_t portId, bool* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::isConnected(int32_t portId, bool* _aidl_return) {
     // Maintain port connection status and update on hotplug event
     if (portId <= mTotalPorts && portId >= 1) {
         *_aidl_return = mPortConnectionStatus[portId];
@@ -51,7 +52,8 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus HdmiMock::setCallback(const std::shared_ptr<IHdmiCallback>& callback) {
+ScopedAStatus HdmiConnectionMock::setCallback(
+        const std::shared_ptr<IHdmiConnectionCallback>& callback) {
     if (mCallback != nullptr) {
         mCallback = nullptr;
     }
@@ -67,7 +69,7 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus HdmiMock::setHpdSignal(HpdSignal signal) {
+ScopedAStatus HdmiConnectionMock::setHpdSignal(HpdSignal signal) {
     if (mHdmiThreadRun) {
         mHpdSignal = signal;
         return ScopedAStatus::ok();
@@ -77,18 +79,18 @@
     }
 }
 
-ScopedAStatus HdmiMock::getHpdSignal(HpdSignal* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::getHpdSignal(HpdSignal* _aidl_return) {
     *_aidl_return = mHpdSignal;
     return ScopedAStatus::ok();
 }
 
-void* HdmiMock::__threadLoop(void* user) {
-    HdmiMock* const self = static_cast<HdmiMock*>(user);
+void* HdmiConnectionMock::__threadLoop(void* user) {
+    HdmiConnectionMock* const self = static_cast<HdmiConnectionMock*>(user);
     self->threadLoop();
     return 0;
 }
 
-int HdmiMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
+int HdmiConnectionMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
     if (msgCount <= 0 || !buf) {
         return 0;
     }
@@ -104,7 +106,7 @@
     return ret;
 }
 
-void HdmiMock::printEventBuf(const char* msg_buf, int len) {
+void HdmiConnectionMock::printEventBuf(const char* msg_buf, int len) {
     int i, size = 0;
     const int bufSize = MESSAGE_BODY_MAX_LENGTH * 3;
     // Use 2 characters for each byte in the message plus 1 space
@@ -117,7 +119,7 @@
     ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
 }
 
-void HdmiMock::handleHotplugMessage(unsigned char* msgBuf) {
+void HdmiConnectionMock::handleHotplugMessage(unsigned char* msgBuf) {
     bool connected = ((msgBuf[3]) & 0xf) > 0;
     int32_t portId = static_cast<uint32_t>(msgBuf[0] & 0xf);
 
@@ -140,7 +142,7 @@
     }
 }
 
-void HdmiMock::threadLoop() {
+void HdmiConnectionMock::threadLoop() {
     ALOGD("[halimp_aidl] threadLoop start.");
     unsigned char msgBuf[MESSAGE_BODY_MAX_LENGTH];
     int r = -1;
@@ -172,7 +174,7 @@
     ALOGD("[halimp_aidl] thread end.");
 }
 
-HdmiMock::HdmiMock() {
+HdmiConnectionMock::HdmiConnectionMock() {
     ALOGE("[halimp_aidl] Opening a virtual HDMI HAL for testing and virtual machine.");
     mCallback = nullptr;
     mPortInfos.resize(mTotalPorts);
@@ -188,6 +190,7 @@
 }
 
 }  // namespace implementation
+}  // namespace connection
 }  // namespace hdmi
 }  // namespace tv
 }  // namespace hardware
diff --git a/tv/hdmi/aidl/default/HdmiMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
similarity index 69%
rename from tv/hdmi/aidl/default/HdmiMock.h
rename to tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index 51abaff..b879e51 100644
--- a/tv/hdmi/aidl/default/HdmiMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
-#include <aidl/android/hardware/tv/hdmi/Result.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/Result.h>
 #include <algorithm>
 #include <vector>
 
@@ -25,25 +25,27 @@
 namespace hardware {
 namespace tv {
 namespace hdmi {
+namespace connection {
 namespace implementation {
 
-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;
+using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::Result;
 
 #define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
 #define MESSAGE_BODY_MAX_LENGTH 4
 
-struct HdmiMock : public BnHdmi {
-    HdmiMock();
+struct HdmiConnectionMock : public BnHdmiConnection {
+    HdmiConnectionMock();
 
     ::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 setCallback(
+            const std::shared_ptr<IHdmiConnectionCallback>& callback) override;
     ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal) override;
     ::ndk::ScopedAStatus getHpdSignal(HpdSignal* _aidl_return) override;
 
@@ -57,7 +59,7 @@
 
   private:
     static void serviceDied(void* cookie);
-    std::shared_ptr<IHdmiCallback> mCallback;
+    std::shared_ptr<IHdmiConnectionCallback> mCallback;
 
     // Variables for the virtual HDMI hal impl
     std::vector<HdmiPortInfo> mPortInfos;
@@ -79,6 +81,7 @@
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 };
 }  // namespace implementation
+}  // namespace connection
 }  // namespace hdmi
 }  // Namespace tv
 }  // namespace hardware
diff --git a/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
new file mode 100644
index 0000000..9e37e61
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
@@ -0,0 +1,5 @@
+service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi.connection-service
+    interface aidl android.hardware.tv.hdmi.connection.IHdmiConnection/default
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
similarity index 66%
copy from tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
copy to tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
index a03c199..144fef1 100644
--- a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
@@ -1,9 +1,9 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
-        <name>android.hardware.tv.hdmi</name>
+        <name>android.hardware.tv.hdmi.connection</name>
         <version>1</version>
         <interface>
-            <name>IHdmi</name>
+            <name>IHdmiConnection</name>
             <instance>default</instance>
         </interface>
     </hal>
diff --git a/tv/hdmi/aidl/default/fuzzer.cpp b/tv/hdmi/connection/aidl/default/fuzzer.cpp
similarity index 83%
rename from tv/hdmi/aidl/default/fuzzer.cpp
rename to tv/hdmi/connection/aidl/default/fuzzer.cpp
index 06a2bc0..c5e33fa 100644
--- a/tv/hdmi/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/connection/aidl/default/fuzzer.cpp
@@ -13,16 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <HdmiMock.h>
+#include <HdmiConnectionMock.h>
 #include <fuzzbinder/libbinder_ndk_driver.h>
 #include <fuzzer/FuzzedDataProvider.h>
 
 using android::fuzzService;
-using android::hardware::tv::hdmi::implementation::HdmiMock;
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
 using ndk::SharedRefBase;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    auto hdmiAidl = SharedRefBase::make<HdmiMock>();
+    auto hdmiAidl = SharedRefBase::make<HdmiConnectionMock>();
 
     fuzzService(hdmiAidl->asBinder().get(), FuzzedDataProvider(data, size));
 
diff --git a/tv/hdmi/aidl/default/serviceMock.cpp b/tv/hdmi/connection/aidl/default/serviceMock.cpp
similarity index 74%
rename from tv/hdmi/aidl/default/serviceMock.cpp
rename to tv/hdmi/connection/aidl/default/serviceMock.cpp
index 1d8bf51..223c578 100644
--- a/tv/hdmi/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/connection/aidl/default/serviceMock.cpp
@@ -14,23 +14,23 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.hdmi-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.connection-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 "HdmiMock.h"
+#include "HdmiConnectionMock.h"
 
-using android::hardware::tv::hdmi::implementation::HdmiMock;
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
 
 int main() {
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
 
-    std::shared_ptr<HdmiMock> hdmiAidl = ndk::SharedRefBase::make<HdmiMock>();
-    const std::string instance = std::string() + HdmiMock::descriptor + "/default";
+    std::shared_ptr<HdmiConnectionMock> hdmiAidl = ndk::SharedRefBase::make<HdmiConnectionMock>();
+    const std::string instance = std::string() + HdmiConnectionMock::descriptor + "/default";
     binder_status_t status =
             AServiceManager_addService(hdmiAidl->asBinder().get(), instance.c_str());
     CHECK_EQ(status, STATUS_OK);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/connection/aidl/vts/functional/Android.bp
similarity index 85%
copy from tv/earc/aidl/vts/functional/Android.bp
copy to tv/hdmi/connection/aidl/vts/functional/Android.bp
index 797547e..fc8e2f7 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/connection/aidl/vts/functional/Android.bp
@@ -17,14 +17,14 @@
 }
 
 cc_test {
-    name: "VtsHalTvEArcAidlTargetTest",
+    name: "VtsHalTvHdmiConnectionAidlTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
-    srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+    srcs: ["VtsHalTvHdmiConnectionAidlTargetTest.cpp"],
     static_libs: [
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
new file mode 100644
index 0000000..69f7ef5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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 "Hdmi_Connection_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnectionCallback.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::hdmi::connection::BnHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::ndk::SpAIBinder;
+
+#define INCORRECT_VENDOR_ID 0x00
+#define TV_PHYSICAL_ADDRESS 0x0000
+
+// The main test class for TV HDMI Connection HAL.
+class HdmiConnectionTest : public ::testing::TestWithParam<std::string> {
+    static void serviceDied(void* /* cookie */) {
+        ALOGE("VtsHalTvHdmiConnectionAidlTargetTest died");
+    }
+
+  public:
+    void SetUp() override {
+        hdmiConnection = IHdmiConnection::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(hdmiConnection, nullptr);
+        ALOGI("%s: getService() for hdmiConnection is %s", __func__,
+              hdmiConnection->isRemote() ? "remote" : "local");
+
+        hdmiConnectionCallback = ::ndk::SharedRefBase::make<HdmiConnectionCallback>();
+        ASSERT_NE(hdmiConnectionCallback, nullptr);
+        hdmiConnectionDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+        ASSERT_EQ(AIBinder_linkToDeath(hdmiConnection->asBinder().get(),
+                                       hdmiConnectionDeathRecipient.get(), 0),
+                  STATUS_OK);
+    }
+
+    class HdmiConnectionCallback : public BnHdmiConnectionCallback {
+      public:
+        ::ndk::ScopedAStatus onHotplugEvent(bool connected __unused, int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+    };
+
+    std::shared_ptr<IHdmiConnection> hdmiConnection;
+    std::shared_ptr<IHdmiConnectionCallback> hdmiConnectionCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient hdmiConnectionDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiConnectionTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, HdmiConnectionTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IHdmiConnection::descriptor)),
+        android::PrintInstanceNameToString);
+
+TEST_P(HdmiConnectionTest, SetCallback) {
+    ASSERT_TRUE(hdmiConnection->setCallback(::ndk::SharedRefBase::make<HdmiConnectionCallback>())
+                        .isOk());
+}
+
+TEST_P(HdmiConnectionTest, GetPortInfo) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+
+    bool cecSupportedOnDevice = false;
+    for (size_t i = 0; i < ports.size(); ++i) {
+        EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) ||
+                    (ports[i].type == HdmiPortType::INPUT));
+        if (ports[i].portId == 0) {
+            ALOGW("%s: Port id should start from 1", __func__);
+        }
+        cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported;
+    }
+    EXPECT_NE(cecSupportedOnDevice, false) << "At least one port should support CEC";
+}
+
+TEST_P(HdmiConnectionTest, IsConnected) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+    for (size_t i = 0; i < ports.size(); ++i) {
+        bool connected;
+        ASSERT_TRUE(hdmiConnection->isConnected(ports[i].portId, &connected).isOk());
+    }
+}
+
+TEST_P(HdmiConnectionTest, HdpSignal) {
+    HpdSignal originalSignal;
+    HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
+    HpdSignal readSignal;
+    ASSERT_TRUE(hdmiConnection->getHpdSignal(&originalSignal).isOk());
+    ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
+    ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
+    EXPECT_EQ(readSignal, signal);
+    signal = HpdSignal::HDMI_HPD_PHYSICAL;
+    ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
+    ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
+    EXPECT_EQ(readSignal, signal);
+    ASSERT_TRUE(hdmiConnection->setHpdSignal(originalSignal).isOk());
+}
diff --git a/tv/earc/aidl/Android.bp b/tv/hdmi/earc/aidl/Android.bp
similarity index 84%
copy from tv/earc/aidl/Android.bp
copy to tv/hdmi/earc/aidl/Android.bp
index 5db6032..d76cc1b 100644
--- a/tv/earc/aidl/Android.bp
+++ b/tv/hdmi/earc/aidl/Android.bp
@@ -17,9 +17,10 @@
 }
 
 aidl_interface {
-    name: "android.hardware.tv.earc",
+    name: "android.hardware.tv.hdmi.earc",
     vendor_available: true,
-    srcs: ["android/hardware/tv/earc/*.aidl"],
+    srcs: ["android/hardware/tv/hdmi/earc/*.aidl"],
+    imports: ["android.hardware.tv.hdmi.connection-V1"],
     stability: "vintf",
     backend: {
         java: {
diff --git a/tv/earc/aidl/OWNERS b/tv/hdmi/earc/aidl/OWNERS
similarity index 100%
rename from tv/earc/aidl/OWNERS
rename to tv/hdmi/earc/aidl/OWNERS
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
similarity index 90%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
index 552bb46..1ea7df7 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -31,12 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.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);
+  void setCallback(in android.hardware.tv.hdmi.earc.IEArcCallback callback);
+  android.hardware.tv.hdmi.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/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
similarity index 92%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
index ef99824..1730dcf 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 @VintfStability
 interface IEArcCallback {
-  oneway void onStateChange(in android.hardware.tv.earc.IEArcStatus status, in int portId);
+  oneway void onStateChange(in android.hardware.tv.hdmi.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/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
similarity index 97%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index 729c657..29d4ea9 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 @Backing(type="byte") @VintfStability
 enum IEArcStatus {
   STATUS_IDLE = 0,
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
similarity index 97%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
index 3679d3b..b248f41 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
@@ -31,7 +31,7 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 @VintfStability
 enum Result {
   SUCCESS = 0,
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
similarity index 75%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
index bb8dabf..a2dde6a 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 
-import android.hardware.tv.earc.IEArcCallback;
-import android.hardware.tv.earc.IEArcStatus;
+import android.hardware.tv.hdmi.earc.IEArcCallback;
+import android.hardware.tv.hdmi.earc.IEArcStatus;
 
 /**
  * eARC HAL interface definition
@@ -30,11 +30,13 @@
      * 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.
+     * @throws ServiceSpecificException with error code set to
+     *         {@code Result::FAILURE_NOT_SUPPORTED} if the eARC enabled setting could not be set
+     *                                               because this is not supported.
+     *         {@code Result::FAILURE_INVALID_ARGS} if the eARC enabled setting could not be set
+     *                                              because the method argument is invalid.
+     *         {@code Result::FAILURE_UNKNOWN} if the eARC enabled setting could not be set because
+     *                                         there was an unknown failure.
      */
     void setEArcEnabled(in boolean enabled);
 
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
similarity index 95%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
index c70191f..a11924b 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 
-import android.hardware.tv.earc.IEArcStatus;
+import android.hardware.tv.hdmi.earc.IEArcStatus;
 
 /**
  * eARC HAL callback methods
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
similarity index 95%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index ecb1c85..de1aaf1 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 
 /**
  * eARC HAL connection states
diff --git a/tv/earc/aidl/android/hardware/tv/earc/Result.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
similarity index 96%
rename from tv/earc/aidl/android/hardware/tv/earc/Result.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
index 054518a..268610d 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/Result.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
 
 /**
  * Result enum for return values. Used by the HDMI related AIDL.
diff --git a/tv/earc/aidl/default/Android.bp b/tv/hdmi/earc/aidl/default/Android.bp
similarity index 79%
rename from tv/earc/aidl/default/Android.bp
rename to tv/hdmi/earc/aidl/default/Android.bp
index 399f029..5d56c2a 100644
--- a/tv/earc/aidl/default/Android.bp
+++ b/tv/hdmi/earc/aidl/default/Android.bp
@@ -17,15 +17,15 @@
 }
 
 cc_binary {
-    name: "android.hardware.tv.earc-service",
-    vintf_fragments: ["android.hardware.tv.earc-service.xml"],
+    name: "android.hardware.tv.hdmi.earc-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.earc-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     cflags: [
         "-Wall",
         "-Wextra",
     ],
-    init_rc: ["android.hardware.tv.earc-service.rc"],
+    init_rc: ["android.hardware.tv.hdmi.earc-service.rc"],
     srcs: [
         "serviceMock.cpp",
         "EArcMock.cpp",
@@ -37,15 +37,15 @@
         "libutils",
         "libhardware",
         "libhidlbase",
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.earc-V1-ndk",
     ],
 }
 
 cc_fuzz {
-    name: "android.hardware.tv.earc-service_fuzzer",
+    name: "android.hardware.tv.hdmi.earc-service_fuzzer",
     defaults: ["service_fuzzer_defaults"],
     static_libs: [
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.earc-V1-ndk",
         "liblog",
     ],
     srcs: [
diff --git a/tv/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
similarity index 96%
rename from tv/earc/aidl/default/EArcMock.cpp
rename to tv/hdmi/earc/aidl/default/EArcMock.cpp
index 9bccc18..99a845e 100644
--- a/tv/earc/aidl/default/EArcMock.cpp
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.earc"
+#define LOG_TAG "android.hardware.tv.hdmi.earc"
 #include <android-base/logging.h>
 #include <fcntl.h>
 #include <utils/Log.h>
@@ -26,6 +26,7 @@
 namespace android {
 namespace hardware {
 namespace tv {
+namespace hdmi {
 namespace earc {
 namespace implementation {
 
@@ -84,7 +85,7 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus EArcMock::reportCapabilities(const std::vector<uint8_t> capabilities,
+ScopedAStatus EArcMock::reportCapabilities(const std::vector<uint8_t>& capabilities,
                                            int32_t portId) {
     if (mCallback != nullptr) {
         mCallback->onCapabilitiesReported(capabilities, portId);
@@ -114,6 +115,7 @@
 
 }  // namespace implementation
 }  // namespace earc
+}  // namespace hdmi
 }  // namespace tv
 }  // namespace hardware
 }  // namespace android
diff --git a/tv/earc/aidl/default/EArcMock.h b/tv/hdmi/earc/aidl/default/EArcMock.h
similarity index 82%
rename from tv/earc/aidl/default/EArcMock.h
rename to tv/hdmi/earc/aidl/default/EArcMock.h
index 9081950..8af9706 100644
--- a/tv/earc/aidl/default/EArcMock.h
+++ b/tv/hdmi/earc/aidl/default/EArcMock.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <aidl/android/hardware/tv/earc/BnEArc.h>
-#include <aidl/android/hardware/tv/earc/Result.h>
+#include <aidl/android/hardware/tv/hdmi/earc/BnEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/Result.h>
 #include <algorithm>
 #include <vector>
 
@@ -24,14 +24,15 @@
 namespace android {
 namespace hardware {
 namespace tv {
+namespace hdmi {
 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;
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::hdmi::earc::Result;
 
 struct EArcMock : public BnEArc {
     EArcMock();
@@ -42,7 +43,7 @@
     ::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,
+    ::ndk::ScopedAStatus reportCapabilities(const std::vector<uint8_t>& capabilities,
                                             int32_t portId);
     ::ndk::ScopedAStatus changeState(const IEArcStatus status, int32_t portId);
 
@@ -69,6 +70,7 @@
 };
 }  // namespace implementation
 }  // namespace earc
+}  // Namespace hdmi
 }  // Namespace tv
 }  // namespace hardware
 }  // namespace android
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
new file mode 100644
index 0000000..53bec04
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
@@ -0,0 +1,5 @@
+service vendor.earc-default /vendor/bin/hw/android.hardware.tv.hdmi.earc-service
+    interface aidl android.hardware.tv.hdmi.earc.IEArc/default
+    class hal
+    user system
+    group system
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.xml b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
similarity index 81%
rename from tv/earc/aidl/default/android.hardware.tv.earc-service.xml
rename to tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
index 4d66d98..6f8d03d 100644
--- a/tv/earc/aidl/default/android.hardware.tv.earc-service.xml
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
@@ -1,6 +1,6 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
-        <name>android.hardware.tv.earc</name>
+        <name>android.hardware.tv.hdmi.earc</name>
         <version>1</version>
         <interface>
             <name>IEArc</name>
diff --git a/tv/earc/aidl/default/fuzzer.cpp b/tv/hdmi/earc/aidl/default/fuzzer.cpp
similarity index 93%
rename from tv/earc/aidl/default/fuzzer.cpp
rename to tv/hdmi/earc/aidl/default/fuzzer.cpp
index 5036853..25264ae 100644
--- a/tv/earc/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/earc/aidl/default/fuzzer.cpp
@@ -18,7 +18,7 @@
 #include <fuzzer/FuzzedDataProvider.h>
 
 using android::fuzzService;
-using android::hardware::tv::earc::implementation::EArcMock;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
 using ndk::SharedRefBase;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/tv/earc/aidl/default/serviceMock.cpp b/tv/hdmi/earc/aidl/default/serviceMock.cpp
similarity index 90%
rename from tv/earc/aidl/default/serviceMock.cpp
rename to tv/hdmi/earc/aidl/default/serviceMock.cpp
index 1ea7262..0878e76 100644
--- a/tv/earc/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/earc/aidl/default/serviceMock.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.tv.earc-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.earc-service-shim"
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
@@ -23,7 +23,7 @@
 #include <utils/Log.h>
 #include "EArcMock.h"
 
-using android::hardware::tv::earc::implementation::EArcMock;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
 
 int main() {
     ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/earc/aidl/vts/functional/Android.bp
similarity index 87%
rename from tv/earc/aidl/vts/functional/Android.bp
rename to tv/hdmi/earc/aidl/vts/functional/Android.bp
index 797547e..36fbf56 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/earc/aidl/vts/functional/Android.bp
@@ -17,14 +17,14 @@
 }
 
 cc_test {
-    name: "VtsHalTvEArcAidlTargetTest",
+    name: "VtsHalTvHdmiEArcAidlTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
-    srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+    srcs: ["VtsHalTvHdmiEArcAidlTargetTest.cpp"],
     static_libs: [
-        "android.hardware.tv.earc-V1-ndk",
+        "android.hardware.tv.hdmi.earc-V1-ndk",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
similarity index 88%
rename from tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
rename to tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
index 12f48c3..3cd8577 100644
--- a/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
+++ b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
@@ -18,9 +18,9 @@
 
 #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 <aidl/android/hardware/tv/hdmi/earc/BnEArcCallback.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArcStatus.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -29,10 +29,10 @@
 #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 ::aidl::android::hardware::tv::hdmi::earc::BnEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
 using ::ndk::SpAIBinder;
 
 // The main test class for TV EARC HAL.
diff --git a/tv/earc/aidl/Android.bp b/usb/gadget/aidl/Android.bp
similarity index 67%
copy from tv/earc/aidl/Android.bp
copy to usb/gadget/aidl/Android.bp
index 5db6032..cb8560a 100644
--- a/tv/earc/aidl/Android.bp
+++ b/usb/gadget/aidl/Android.bp
@@ -13,15 +13,23 @@
 // limitations under the License.
 
 package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
 aidl_interface {
-    name: "android.hardware.tv.earc",
+    name: "android.hardware.usb.gadget",
     vendor_available: true,
-    srcs: ["android/hardware/tv/earc/*.aidl"],
+    srcs: ["android/hardware/usb/gadget/*.aidl"],
     stability: "vintf",
     backend: {
+        cpp: {
+            enabled: false,
+        },
         java: {
             sdk_version: "module_current",
         },
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
similarity index 84%
copy from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
copy to usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
index b6b0eb3..c3f26d5 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -31,12 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.usb.gadget;
 @VintfStability
-enum Result {
-  SUCCESS = 0,
-  FAILURE_UNKNOWN = 1,
-  FAILURE_INVALID_ARGS = 2,
-  FAILURE_INVALID_STATE = 3,
-  FAILURE_NOT_SUPPORTED = 4,
+parcelable GadgetFunction {
+  const long NONE = 0;
+  const long ADB = 1;
+  const long ACCESSORY = 2;
+  const long MTP = 4;
+  const long MIDI = 8;
+  const long PTP = 16;
+  const long RNDIS = 32;
+  const long AUDIO_SOURCE = 64;
+  const long NCM = 1024;
 }
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
similarity index 78%
copy from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
copy to usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
index b6b0eb3..ef45f8b 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -31,12 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.hdmi;
+package android.hardware.usb.gadget;
 @VintfStability
-enum Result {
-  SUCCESS = 0,
-  FAILURE_UNKNOWN = 1,
-  FAILURE_INVALID_ARGS = 2,
-  FAILURE_INVALID_STATE = 3,
-  FAILURE_NOT_SUPPORTED = 4,
+interface IUsbGadget {
+  oneway void setCurrentUsbFunctions(in long functions, in android.hardware.usb.gadget.IUsbGadgetCallback callback, in long timeoutMs, long transactionId);
+  oneway void getCurrentUsbFunctions(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void getUsbSpeed(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void reset();
 }
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
similarity index 80%
copy from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
copy to usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
index 1918765..9de68de 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -31,8 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.tv.cec;
+package android.hardware.usb.gadget;
 @VintfStability
-interface IHdmiCecCallback {
-  oneway void onCecMessage(in android.hardware.tv.cec.CecMessage message);
+interface IUsbGadgetCallback {
+  oneway void setCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getUsbSpeedCb(in android.hardware.usb.gadget.UsbSpeed speed, long transactionId);
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl
similarity index 90%
rename from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl
rename to usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl
index 336f9b5..bdcf685 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl
@@ -31,12 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.audio.core;
+package android.hardware.usb.gadget;
 @Backing(type="int") @VintfStability
-enum AudioMode {
-  NORMAL = 0,
-  RINGTONE = 1,
-  IN_CALL = 2,
-  IN_COMMUNICATION = 3,
-  CALL_SCREEN = 4,
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  FUNCTIONS_APPLIED = 2,
+  FUNCTIONS_NOT_APPLIED = 3,
+  CONFIGURATION_NOT_SUPPORTED = 4,
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
similarity index 89%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl
copy to usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
index 336f9b5..0f54ee5 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioMode.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -31,12 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.audio.core;
+package android.hardware.usb.gadget;
 @Backing(type="int") @VintfStability
-enum AudioMode {
-  NORMAL = 0,
-  RINGTONE = 1,
-  IN_CALL = 2,
-  IN_COMMUNICATION = 3,
-  CALL_SCREEN = 4,
+enum UsbSpeed {
+  UNKNOWN = 0,
+  LOWSPEED = 1,
+  FULLSPEED = 2,
+  HIGHSPEED = 3,
+  SUPERSPEED = 4,
+  SUPERSPEED_10Gb = 5,
+  SUPERSPEED_20Gb = 6,
 }
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
new file mode 100644
index 0000000..d82b427
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.usb.gadget;
+
+@VintfStability
+parcelable GadgetFunction {
+    /**
+     * Removes all the functions and pulls down the gadget.
+     */
+    const long NONE = 0;
+    /**
+     * Android Debug Bridge function.
+     */
+    const long ADB = 1;
+    /**
+     * Android open accessory protocol function.
+     */
+    const long ACCESSORY = 1 << 1;
+    /**
+     * Media Transfer protocol function.
+     */
+    const long MTP = 1 << 2;
+    /**
+     * Peripheral mode USB Midi function.
+     */
+    const long MIDI = 1 << 3;
+    /**
+     * Picture transfer protocol function.
+     */
+    const long PTP = 1 << 4;
+    /**
+     * Tethering function.
+     */
+    const long RNDIS = 1 << 5;
+    /**
+     * AOAv2.0 - Audio Source function.
+     */
+    const long AUDIO_SOURCE = 1 << 6;
+    /**
+     * NCM - NCM function.
+     */
+    const long NCM = 1 << 10;
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
new file mode 100644
index 0000000..da644d6
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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.usb.gadget;
+
+import android.hardware.usb.gadget.GadgetFunction;
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+
+@VintfStability
+oneway interface IUsbGadget {
+    /**
+     * This function is used to set the current USB gadget configuration.
+     * Usb gadget needs to be reset if an USB configuration is already.
+     *
+     * @param functions The GadgetFunction bitmap. See GadgetFunction for
+     *                  the value of each bit.
+     * @param callback IUsbGadgetCallback::setCurrentUsbFunctionsCb used to
+     *                 propagate back the status.
+     * @param timeoutMs The maximum time (in milliseconds) within which the
+     *                IUsbGadgetCallback needs to be returned.
+     * @param transactionId ID to be used when invoking the callback.
+     *
+     */
+    void setCurrentUsbFunctions(in long functions, in IUsbGadgetCallback callback,
+            in long timeoutMs, long transactionId);
+
+    /**
+     * This function is used to query the USB functions included in the
+     * current USB configuration.
+     *
+     * @param callback IUsbGadgetCallback::getCurrentUsbFunctionsCb used to
+     *                 propagate the current functions list.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getCurrentUsbFunctions(in IUsbGadgetCallback callback, long transactionId);
+
+    /**
+     * The function is used to query current USB speed.
+     *
+     * @param callback IUsbGadgetCallback::getUsbSpeedCb used to propagate
+     *                 current USB speed.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getUsbSpeed(in IUsbGadgetCallback callback, long transactionId);
+
+    /**
+     * This function is used to reset USB gadget driver.
+     * Performs USB data connection reset. The connection will disconnect and
+     * reconnect.
+     */
+    void reset();
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
new file mode 100644
index 0000000..5a682d6
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.usb.gadget;
+
+import android.hardware.usb.gadget.GadgetFunction;
+import android.hardware.usb.gadget.Status;
+import android.hardware.usb.gadget.UsbSpeed;
+
+@VintfStability
+oneway interface IUsbGadgetCallback {
+    /**
+     * Callback function used to propagate the status of configuration
+     * switch to the caller.
+     *
+     * @param functions list of functions defined by GadgetFunction
+     *                  included in the current USB gadget composition.
+     * @param status SUCCESS when the functions are applied.
+     *               FUNCTIONS_NOT_SUPPORTED when the configuration is
+     *                                       not supported.
+     *               ERROR otherwise.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void setCurrentUsbFunctionsCb(in long functions, in Status status, long transactionId);
+
+    /**
+     * Callback function used to propagate the current USB gadget
+     * configuration.
+     * @param functions The GadgetFunction bitmap. See GadgetFunction for
+     *                  the value of each bit.
+     * @param status FUNCTIONS_APPLIED when list of functions have been
+     *                                 applied.
+     *               FUNCTIONS_NOT_APPLIED when the functions have not
+     *                                     been applied.
+     *               ERROR otherwise.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getCurrentUsbFunctionsCb(in long functions, in Status status, long transactionId);
+
+    /**
+     * Used to convey the current USB speed to the caller.
+     * Must be called either when USB state changes due to USB enumeration or
+     * when caller requested for USB speed through getUsbSpeed.
+     *
+     * @param speed USB Speed defined by UsbSpeed showed current USB
+     *              connection speed.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getUsbSpeedCb(in UsbSpeed speed, long transactionId);
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/Status.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/Status.aidl
new file mode 100644
index 0000000..8d8c3e3
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/Status.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.
+ */
+
+package android.hardware.usb.gadget;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    SUCCESS = 0,
+    /**
+     * Error value when the HAL operation fails for reasons not listed here.
+     */
+    ERROR = 1,
+    /**
+     * USB configuration applied successfully.
+     */
+    FUNCTIONS_APPLIED = 2,
+    /**
+     * USB confgiuration failed to apply.
+     */
+    FUNCTIONS_NOT_APPLIED = 3,
+    /**
+     * USB configuration not supported.
+     */
+    CONFIGURATION_NOT_SUPPORTED = 4,
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
new file mode 100644
index 0000000..0492757
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.usb.gadget;
+
+@VintfStability
+@Backing(type="int")
+enum UsbSpeed {
+    /**
+     * UNKNOWN - Not Connected or Unsupported Speed
+     */
+    UNKNOWN = 0,
+    /**
+     * USB Low Speed
+     */
+    LOWSPEED = 1,
+    /**
+     * USB Full Speed
+     */
+    FULLSPEED = 2,
+    /**
+     * USB High Speed
+     */
+    HIGHSPEED = 3,
+    /**
+     * USB Super Speed
+     */
+    SUPERSPEED = 4,
+    /**
+     * USB Super Speed 10Gbps
+     */
+    SUPERSPEED_10Gb = 5,
+    /**
+     * USB Super Speed 20Gbps
+     */
+    SUPERSPEED_20Gb = 6,
+}
diff --git a/usb/gadget/aidl/default/Android.bp b/usb/gadget/aidl/default/Android.bp
new file mode 100644
index 0000000..2ea0e12
--- /dev/null
+++ b/usb/gadget/aidl/default/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "hardware_interfaces_license",
+    ],
+}
+cc_binary {
+    name: "android.hardware.usb.gadget-service.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.usb.gadget-service.example.rc"],
+    vintf_fragments: [
+        "android.hardware.usb.gadget-service.example.xml",
+    ],
+    vendor: true,
+    srcs: ["service_gadget.cpp", "UsbGadget.cpp"],
+    cflags: ["-Wall", "-Werror"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+        "libhardware",
+	"android.hardware.usb.gadget-V1-ndk",
+	"android.frameworks.stats-V1-ndk",
+        "libcutils",
+	"libbinder_ndk",
+    ],
+}
diff --git a/usb/gadget/aidl/default/UsbGadget.cpp b/usb/gadget/aidl/default/UsbGadget.cpp
new file mode 100644
index 0000000..72cf681
--- /dev/null
+++ b/usb/gadget/aidl/default/UsbGadget.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget.aidl-service"
+
+#include "UsbGadget.h"
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <aidl/android/frameworks/stats/IStats.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+string enabledPath;
+constexpr char kHsi2cPath[] = "/sys/devices/platform/10d50000.hsi2c";
+constexpr char kI2CPath[] = "/sys/devices/platform/10d50000.hsi2c/i2c-";
+constexpr char kAccessoryLimitCurrent[] = "i2c-max77759tcpc/usb_limit_accessory_current";
+constexpr char kAccessoryLimitCurrentEnable[] = "i2c-max77759tcpc/usb_limit_accessory_enable";
+
+UsbGadget::UsbGadget() : mGadgetIrqPath("") {}
+
+Status UsbGadget::getUsbGadgetIrqPath() {
+    std::string irqs;
+    size_t read_pos = 0;
+    size_t found_pos = 0;
+
+    if (!ReadFileToString(kProcInterruptsPath, &irqs)) {
+        ALOGE("cannot read all interrupts");
+        return Status::ERROR;
+    }
+
+    while (true) {
+        found_pos = irqs.find_first_of("\n", read_pos);
+        if (found_pos == std::string::npos) {
+            ALOGI("the string of all interrupts is unexpected");
+            return Status::ERROR;
+        }
+
+        std::string single_irq = irqs.substr(read_pos, found_pos - read_pos);
+
+        if (single_irq.find("dwc3", 0) != std::string::npos) {
+            unsigned int dwc3_irq_number;
+            size_t dwc3_pos = single_irq.find_first_of(":");
+            if (!ParseUint(single_irq.substr(0, dwc3_pos), &dwc3_irq_number)) {
+                ALOGI("unknown IRQ strings");
+                return Status::ERROR;
+            }
+
+            mGadgetIrqPath = kProcIrqPath + single_irq.substr(0, dwc3_pos) + kSmpAffinityList;
+            break;
+        }
+
+        if (found_pos == irqs.npos) {
+            ALOGI("USB gadget doesn't start");
+            return Status::ERROR;
+        }
+
+        read_pos = found_pos + 1;
+    }
+
+    return Status::SUCCESS;
+}
+
+void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) {
+    UsbGadget* gadget = (UsbGadget*)payload;
+    gadget->mCurrentUsbFunctionsApplied = functionsApplied;
+}
+
+ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
+                                                int64_t in_transactionId) {
+    ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
+            mCurrentUsbFunctions,
+            mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
+            in_transactionId);
+    if (!ret.isOk())
+        ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.getDescription().c_str());
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback>& callback,
+                                     int64_t in_transactionId) {
+    std::string current_speed;
+    if (ReadFileToString(SPEED_PATH, &current_speed)) {
+        current_speed = Trim(current_speed);
+        ALOGI("current USB speed is %s", current_speed.c_str());
+        if (current_speed == "low-speed")
+            mUsbSpeed = UsbSpeed::LOWSPEED;
+        else if (current_speed == "full-speed")
+            mUsbSpeed = UsbSpeed::FULLSPEED;
+        else if (current_speed == "high-speed")
+            mUsbSpeed = UsbSpeed::HIGHSPEED;
+        else if (current_speed == "super-speed")
+            mUsbSpeed = UsbSpeed::SUPERSPEED;
+        else if (current_speed == "super-speed-plus")
+            mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
+        else if (current_speed == "UNKNOWN")
+            mUsbSpeed = UsbSpeed::UNKNOWN;
+        else
+            mUsbSpeed = UsbSpeed::UNKNOWN;
+    } else {
+        ALOGE("Fail to read current speed");
+        mUsbSpeed = UsbSpeed::UNKNOWN;
+    }
+
+    if (callback) {
+        ScopedAStatus ret = callback->getUsbSpeedCb(mUsbSpeed, in_transactionId);
+
+        if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
+    }
+
+    return ScopedAStatus::ok();
+}
+
+Status UsbGadget::tearDownGadget() {
+    return Status::SUCCESS;
+}
+
+ScopedAStatus UsbGadget::reset() {
+    return ScopedAStatus::ok();
+}
+
+Status UsbGadget::setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback>& callback,
+                                 uint64_t timeout, int64_t in_transactionId) {
+    bool ffsEnabled = false;
+    if (timeout == 0) {
+        ALOGI("timeout not setup");
+    }
+
+    if ((functions & GadgetFunction::ADB) != 0) {
+        ffsEnabled = true;
+    }
+
+    if ((functions & GadgetFunction::NCM) != 0) {
+        ALOGI("setCurrentUsbFunctions ncm");
+    }
+
+    // Pull up the gadget right away when there are no ffs functions.
+    if (!ffsEnabled) {
+        mCurrentUsbFunctionsApplied = true;
+        if (callback)
+            callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+        return Status::SUCCESS;
+    }
+
+    return Status::SUCCESS;
+}
+
+Status getI2cBusHelper(string* name) {
+    DIR* dp;
+
+    dp = opendir(kHsi2cPath);
+    if (dp != NULL) {
+        struct dirent* ep;
+
+        while ((ep = readdir(dp))) {
+            if (ep->d_type == DT_DIR) {
+                if (string::npos != string(ep->d_name).find("i2c-")) {
+                    std::strtok(ep->d_name, "-");
+                    *name = std::strtok(NULL, "-");
+                }
+            }
+        }
+        closedir(dp);
+        return Status::SUCCESS;
+    }
+
+    ALOGE("Failed to open %s", kHsi2cPath);
+    return Status::ERROR;
+}
+
+ScopedAStatus UsbGadget::setCurrentUsbFunctions(int64_t functions,
+                                                const shared_ptr<IUsbGadgetCallback>& callback,
+                                                int64_t timeoutMs, int64_t in_transactionId) {
+    std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
+    std::string current_usb_power_operation_mode, current_usb_type;
+    std::string usb_limit_sink_enable;
+
+    string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath, path;
+
+    mCurrentUsbFunctions = functions;
+    mCurrentUsbFunctionsApplied = false;
+
+    getI2cBusHelper(&path);
+    accessoryCurrentLimitPath = kI2CPath + path + "/" + kAccessoryLimitCurrent;
+    accessoryCurrentLimitEnablePath = kI2CPath + path + "/" + kAccessoryLimitCurrentEnable;
+
+    // Get the gadget IRQ number before tearDownGadget()
+    if (mGadgetIrqPath.empty()) getUsbGadgetIrqPath();
+
+    // Unlink the gadget and stop the monitor if running.
+    Status status = tearDownGadget();
+    if (status != Status::SUCCESS) {
+        goto error;
+    }
+
+    ALOGI("Returned from tearDown gadget");
+
+    // Leave the gadget pulled down to give time for the host to sense disconnect.
+    // usleep(kDisconnectWaitUs);
+
+    if (functions == GadgetFunction::NONE) {
+        if (callback == NULL)
+            return ScopedAStatus::fromServiceSpecificErrorWithMessage(-1, "callback == NULL");
+        ScopedAStatus ret =
+                callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Error while calling setCurrentUsbFunctionsCb");
+    }
+
+    status = setupFunctions(functions, callback, timeoutMs, in_transactionId);
+    if (status != Status::SUCCESS) {
+        goto error;
+    }
+
+    if (functions & GadgetFunction::NCM) {
+        if (!mGadgetIrqPath.empty()) {
+            if (!WriteStringToFile(BIG_CORE, mGadgetIrqPath))
+                ALOGI("Cannot move gadget IRQ to big core, path:%s", mGadgetIrqPath.c_str());
+        }
+    } else {
+        if (!mGadgetIrqPath.empty()) {
+            if (!WriteStringToFile(MEDIUM_CORE, mGadgetIrqPath))
+                ALOGI("Cannot move gadget IRQ to medium core, path:%s", mGadgetIrqPath.c_str());
+        }
+    }
+
+    if (ReadFileToString(CURRENT_USB_TYPE_PATH, &current_usb_type))
+        current_usb_type = Trim(current_usb_type);
+
+    if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, &current_usb_power_operation_mode))
+        current_usb_power_operation_mode = Trim(current_usb_power_operation_mode);
+
+    if (functions & GadgetFunction::ACCESSORY && current_usb_type == "Unknown SDP [CDP] DCP" &&
+        (current_usb_power_operation_mode == "default" ||
+         current_usb_power_operation_mode == "1.5A")) {
+        if (!WriteStringToFile("1300000", accessoryCurrentLimitPath)) {
+            ALOGI("Write 1.3A to limit current fail");
+        } else {
+            if (!WriteStringToFile("1", accessoryCurrentLimitEnablePath)) {
+                ALOGI("Enable limit current fail");
+            }
+        }
+    } else {
+        if (!WriteStringToFile("0", accessoryCurrentLimitEnablePath))
+            ALOGI("unvote accessory limit current failed");
+    }
+
+    ALOGI("Usb Gadget setcurrent functions called successfully");
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            -1, "Usb Gadget setcurrent functions called successfully");
+
+error:
+    ALOGI("Usb Gadget setcurrent functions failed");
+    if (callback == NULL)
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Usb Gadget setcurrent functions failed");
+    ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, status, in_transactionId);
+    if (!ret.isOk())
+        ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            -1, "Error while calling setCurrentUsbFunctionsCb");
+}
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/usb/gadget/aidl/default/UsbGadget.h b/usb/gadget/aidl/default/UsbGadget.h
new file mode 100644
index 0000000..5060194
--- /dev/null
+++ b/usb/gadget/aidl/default/UsbGadget.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/usb/gadget/BnUsbGadget.h>
+#include <aidl/android/hardware/usb/gadget/BnUsbGadgetCallback.h>
+#include <aidl/android/hardware/usb/gadget/GadgetFunction.h>
+#include <aidl/android/hardware/usb/gadget/IUsbGadget.h>
+#include <aidl/android/hardware/usb/gadget/IUsbGadgetCallback.h>
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <sched.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+using ::aidl::android::hardware::usb::gadget::GadgetFunction;
+using ::aidl::android::hardware::usb::gadget::IUsbGadget;
+using ::aidl::android::hardware::usb::gadget::IUsbGadgetCallback;
+using ::aidl::android::hardware::usb::gadget::Status;
+using ::aidl::android::hardware::usb::gadget::UsbSpeed;
+using ::android::base::GetProperty;
+using ::android::base::ParseUint;
+using ::android::base::ReadFileToString;
+using ::android::base::SetProperty;
+using ::android::base::Trim;
+using ::android::base::unique_fd;
+using ::android::base::WriteStringToFile;
+using ::ndk::ScopedAStatus;
+using ::std::shared_ptr;
+using ::std::string;
+
+constexpr char kGadgetName[] = "11110000.dwc3";
+constexpr char kProcInterruptsPath[] = "/proc/interrupts";
+constexpr char kProcIrqPath[] = "/proc/irq/";
+constexpr char kSmpAffinityList[] = "/smp_affinity_list";
+#ifndef UDC_PATH
+#define UDC_PATH "/sys/class/udc/11110000.dwc3/"
+#endif
+// static MonitorFfs monitorFfs(kGadgetName);
+
+#define SPEED_PATH UDC_PATH "current_speed"
+
+#define BIG_CORE "6"
+#define MEDIUM_CORE "4"
+
+#define POWER_SUPPLY_PATH "/sys/class/power_supply/usb/"
+#define USB_PORT0_PATH "/sys/class/typec/port0/"
+
+#define CURRENT_MAX_PATH POWER_SUPPLY_PATH "current_max"
+#define CURRENT_USB_TYPE_PATH POWER_SUPPLY_PATH "usb_type"
+#define CURRENT_USB_POWER_OPERATION_MODE_PATH USB_PORT0_PATH "power_operation_mode"
+
+struct UsbGadget : public BnUsbGadget {
+    UsbGadget();
+
+    // Makes sure that only one request is processed at a time.
+    std::mutex mLockSetCurrentFunction;
+    std::string mGadgetIrqPath;
+    long mCurrentUsbFunctions;
+    bool mCurrentUsbFunctionsApplied;
+    UsbSpeed mUsbSpeed;
+
+    ScopedAStatus setCurrentUsbFunctions(int64_t functions,
+                                         const shared_ptr<IUsbGadgetCallback>& callback,
+                                         int64_t timeoutMs, int64_t in_transactionId) override;
+
+    ScopedAStatus getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
+                                         int64_t in_transactionId) override;
+
+    ScopedAStatus reset() override;
+
+    ScopedAStatus getUsbSpeed(const shared_ptr<IUsbGadgetCallback>& callback,
+                              int64_t in_transactionId) override;
+
+  private:
+    Status tearDownGadget();
+    Status getUsbGadgetIrqPath();
+    Status setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback>& callback,
+                          uint64_t timeout, int64_t in_transactionId);
+};
+
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc
new file mode 100644
index 0000000..b2a8cc0
--- /dev/null
+++ b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.usb_gadget_default /vendor/bin/hw/android.hardware.usb.gadget-service.example
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml
similarity index 69%
rename from tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
rename to usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml
index a03c199..e7eebc3 100644
--- a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
+++ b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml
@@ -1,9 +1,9 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
-        <name>android.hardware.tv.hdmi</name>
+        <name>android.hardware.usb.gadget</name>
         <version>1</version>
         <interface>
-            <name>IHdmi</name>
+            <name>IUsbGadget</name>
             <instance>default</instance>
         </interface>
     </hal>
diff --git a/usb/gadget/aidl/default/service_gadget.cpp b/usb/gadget/aidl/default/service_gadget.cpp
new file mode 100644
index 0000000..88678ab
--- /dev/null
+++ b/usb/gadget/aidl/default/service_gadget.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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include "UsbGadget.h"
+using ::aidl::android::hardware::usb::gadget::UsbGadget;
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<UsbGadget> usbgadget = ndk::SharedRefBase::make<UsbGadget>();
+    const std::string instance = std::string() + UsbGadget::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(usbgadget->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+    ABinderProcess_joinThreadPool();
+    return -1;
+}