libaudiohal: Update stubs for the core HAL

Provide a bit more functional Device and Stream stubs.
Does not call into the HAL yet. Can boot to completion.

To avoid proliferation of TIME_CHECK definitions, put
one true definition into TimeCheck.h.

Bug: 205884982
Test: boot cuttlefish with AIDL enabled
Change-Id: Ia9aa816faee7cc68e23bfcb25188748e1cd8c02a
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
index a5045b9..6d6c594 100644
--- a/include/media/MicrophoneInfo.h
+++ b/include/media/MicrophoneInfo.h
@@ -70,6 +70,9 @@
     }
 
     virtual status_t writeToParcelable(MicrophoneInfoData* parcelable) const {
+#if defined(BACKEND_NDK)
+        using ::aidl::android::convertReinterpret;
+#endif
         parcelable->deviceId = mDeviceId;
         parcelable->portId = mPortId;
         parcelable->type = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(mType));
@@ -98,6 +101,9 @@
     }
 
     virtual status_t readFromParcelable(const MicrophoneInfoData& parcelable) {
+#if defined(BACKEND_NDK)
+        using ::aidl::android::convertReinterpret;
+#endif
         mDeviceId = parcelable.deviceId;
         mPortId = parcelable.portId;
         mType = VALUE_OR_RETURN_STATUS(convertReinterpret<uint32_t>(parcelable.type));
@@ -208,6 +214,10 @@
     int32_t mDirectionality;
 };
 
+#if defined(BACKEND_NDK)
+using ::aidl::ConversionResult;
+#endif
+
 // Conversion routines, according to AidlConversion.h conventions.
 inline ConversionResult<MicrophoneInfo>
 aidl2legacy_MicrophoneInfo(const media::MicrophoneInfoData& aidl) {
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index d151817..8cbe3ea 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -245,12 +245,14 @@
         "latest_android_media_audio_common_types_ndk_shared",
     ],
     srcs: [
+        "DeviceHalAidl.cpp",
         "DevicesFactoryHalEntry.cpp",
         "DevicesFactoryHalAidl.cpp",
         "EffectBufferHalAidl.cpp",
         "EffectHalAidl.cpp",
         "EffectsFactoryHalAidl.cpp",
         "EffectsFactoryHalEntry.cpp",
+        "StreamHalAidl.cpp",
     ],
     static_libs: [
         "android.hardware.common-V2-ndk",
@@ -271,4 +273,4 @@
         "-Wthread-safety",
         "-DBACKEND_NDK",
     ],
-}
\ No newline at end of file
+}
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
new file mode 100644
index 0000000..097ccfd
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -0,0 +1,35 @@
+/*
+ * 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 <string>
+#include <string_view>
+
+namespace android {
+
+class ConversionHelperAidl {
+  protected:
+    ConversionHelperAidl(std::string_view className) : mClassName(className) {}
+
+    const std::string& getClassName() const {
+        return mClassName;
+    }
+
+    const std::string mClassName;
+};
+
+}  // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index d85d960..02e8fa7 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -16,94 +16,149 @@
 
 #define LOG_TAG "DeviceHalAidl"
 
-#include "DeviceHalAidl.h"
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
 
-status_t DeviceHalAidl::getSupportedDevices(uint32_t* devices) {
-    ALOGE("%s not implemented yet devices %p", __func__, devices);
-    return OK;
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
+    // Obsolete.
+    return INVALID_OPERATION;
 }
 
 status_t DeviceHalAidl::initCheck() {
-    ALOGE("%s not implemented yet", __func__);
+    if (mModule == nullptr) return NO_INIT;
+    // HAL modules are already initialized by the time they are published to the SM.
     return OK;
 }
 
 status_t DeviceHalAidl::setVoiceVolume(float volume) {
+    TIME_CHECK();
     mVoiceVolume = volume;
     ALOGE("%s not implemented yet %f", __func__, volume);
     return OK;
 }
 
 status_t DeviceHalAidl::setMasterVolume(float volume) {
+    TIME_CHECK();
     mMasterVolume = volume;
     ALOGE("%s not implemented yet %f", __func__, volume);
     return OK;
 }
 
 status_t DeviceHalAidl::getMasterVolume(float *volume) {
+    TIME_CHECK();
     *volume = mMasterVolume;
     ALOGE("%s not implemented yet %f", __func__, *volume);
     return OK;
 }
 
-status_t DeviceHalAidl::setMode(audio_mode_t mode) {
-    ALOGE("%s not implemented yet %u", __func__, mode);
+status_t DeviceHalAidl::setMode(audio_mode_t mode __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 status_t DeviceHalAidl::setMicMute(bool state) {
+    TIME_CHECK();
     mMicMute = state;
     ALOGE("%s not implemented yet %d", __func__, state);
     return OK;
 }
+
 status_t DeviceHalAidl::getMicMute(bool *state) {
+    TIME_CHECK();
     *state = mMicMute;
     ALOGE("%s not implemented yet %d", __func__, *state);
     return OK;
 }
+
 status_t DeviceHalAidl::setMasterMute(bool state) {
+    TIME_CHECK();
     mMasterMute = state;
     ALOGE("%s not implemented yet %d", __func__, state);
     return OK;
 }
+
 status_t DeviceHalAidl::getMasterMute(bool *state) {
+    TIME_CHECK();
     *state = mMasterMute;
     ALOGE("%s not implemented yet %d", __func__, *state);
     return OK;
 }
 
-status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
-    ALOGE("%s not implemented yet %s", __func__, kvPairs.c_str());
+status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
-    ALOGE("%s not implemented yet %s %s", __func__, keys.c_str(), values->c_str());
+status_t DeviceHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+    TIME_CHECK();
+    values->clear();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
-    ALOGE("%s not implemented yet %p %zu", __func__, config, *size);
+status_t DeviceHalAidl::getInputBufferSize(
+        const struct audio_config* config __unused, size_t* size __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
-                                         audio_output_flags_t flags, struct audio_config* config,
-                                         const char* address,
-                                         sp<StreamOutHalInterface>* outStream) {
-    ALOGE("%s not implemented yet %d %u %u %p %s %p", __func__, handle, devices, flags, config,
-          address, outStream);
+status_t DeviceHalAidl::openOutputStream(
+        audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+        audio_output_flags_t flags __unused, struct audio_config* config,
+        const char* address __unused,
+        sp<StreamOutHalInterface>* outStream) {
+    if (!outStream || !config) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    config->sample_rate = 48000;
+    config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+    StreamDescriptor descriptor;
+    descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+            audio_channel_count_from_out_mask(config->channel_mask);
+    descriptor.bufferSizeFrames = 600;
+    *outStream = sp<StreamOutHalAidl>::make(descriptor, nullptr);
     return OK;
 }
 
-status_t DeviceHalAidl::openInputStream(audio_io_handle_t handle, audio_devices_t devices,
-                                        struct audio_config* config, audio_input_flags_t flags,
-                                        const char* address, audio_source_t source,
-                                        audio_devices_t outputDevice,
-                                        const char* outputDeviceAddress,
-                                        sp<StreamInHalInterface>* inStream) {
-    ALOGE("%s not implemented yet %d %u %u %u %p %s %s %p %d", __func__, handle, devices,
-          outputDevice, flags, config, address, outputDeviceAddress, inStream, source);
+status_t DeviceHalAidl::openInputStream(
+        audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+        struct audio_config* config, audio_input_flags_t flags __unused,
+        const char* address __unused, audio_source_t source __unused,
+        audio_devices_t outputDevice __unused,
+        const char* outputDeviceAddress __unused,
+        sp<StreamInHalInterface>* inStream) {
+    if (!inStream || !config) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    config->sample_rate = 48000;
+    config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+    StreamDescriptor descriptor;
+    descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+            audio_channel_count_from_out_mask(config->channel_mask);
+    descriptor.bufferSizeFrames = 600;
+    *inStream = sp<StreamInHalAidl>::make(descriptor, nullptr);
     return OK;
 }
 
@@ -112,66 +167,94 @@
     return OK;
 }
 
-status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
-                                         const struct audio_port_config* sources,
-                                         unsigned int num_sinks,
-                                         const struct audio_port_config* sinks,
-                                         audio_patch_handle_t* patch) {
-    ALOGE("%s not implemented yet %d %p %d %p %p", __func__, num_sources, sources, num_sinks,
-            sinks, patch);
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources __unused,
+                                         const struct audio_port_config* sources __unused,
+                                         unsigned int num_sinks __unused,
+                                         const struct audio_port_config* sinks __unused,
+                                         audio_patch_handle_t* patch __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
-    ALOGE("%s not implemented yet patch %d", __func__, patch);
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
-    ALOGE("%s not implemented yet config %p", __func__, config);
+status_t DeviceHalAidl::getAudioPort(struct audio_port* port __unused) {
+    TIME_CHECK();
+    ALOGE("%s not implemented yet", __func__);
+    return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port __unused) {
+    TIME_CHECK();
+    ALOGE("%s not implemented yet", __func__);
+    return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 status_t DeviceHalAidl::getMicrophones(
-        std::vector<audio_microphone_characteristic_t>* microphones) {
-    ALOGE("%s not implemented yet microphones %p", __func__, microphones);
+        std::vector<audio_microphone_characteristic_t>* microphones __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) {
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device __unused,
+        sp<EffectHalInterface> effect) {
     if (!effect) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet device %d", __func__, device);
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
-status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device,
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device __unused,
                             sp<EffectHalInterface> effect) {
     if (!effect) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet device %d", __func__, device);
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 status_t DeviceHalAidl::getMmapPolicyInfos(
         media::audio::common::AudioMMapPolicyType policyType __unused,
         std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return base::unexpected(INVALID_OPERATION);
 }
@@ -181,7 +264,10 @@
     return OK;
 };
 
-int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) override {
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return INVALID_OPERATION;
 }
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 5e8a8dd..91d48cc 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -16,14 +16,15 @@
 
 #pragma once
 
+#include <aidl/android/hardware/audio/core/BpModule.h>
 #include <media/audiohal/DeviceHalInterface.h>
 #include <media/audiohal/EffectHalInterface.h>
 
-#include <aidl/android/hardware/audio/core/BpModule.h>
+#include "ConversionHelperAidl.h"
 
 namespace android {
 
-class DeviceHalAidl : public DeviceHalInterface {
+class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl {
   public:
     // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
     status_t getSupportedDevices(uint32_t *devices) override;
@@ -86,6 +87,12 @@
     // Releases an audio patch.
     status_t releaseAudioPatch(audio_patch_handle_t patch) override;
 
+    // Fills the list of supported attributes for a given audio port.
+    status_t getAudioPort(struct audio_port* port) override;
+
+    // Fills the list of supported attributes for a given audio port.
+    status_t getAudioPort(struct audio_port_v7 *port) override;
+
     // Set audio port configuration.
     status_t setAudioPortConfig(const struct audio_port_config* config) override;
 
@@ -111,8 +118,10 @@
     int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
 
   private:
-    friend class DevicesFactoryHalAidl;
-    const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mCore;
+    friend class sp<DeviceHalAidl>;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+    // FIXME: Remove these after implementing calls into the HAL.
     float mMasterVolume = 0.0f;
     float mVoiceVolume = 0.0f;
     bool mMasterMute = false;
@@ -120,11 +129,10 @@
 
     // Can not be constructed directly by clients.
     explicit DeviceHalAidl(
-            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& core)
-        : mCore(core) {}
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
+            : ConversionHelperAidl("DeviceHalAidl"), mModule(module) {}
 
-    // The destructor automatically closes the device.
-    ~DeviceHalAidl();
+    ~DeviceHalAidl() override = default;
 };
 
 } // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index be063ab..12acebd 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
-#define TIME_CHECK() auto timeCheck = \
-        mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
         : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
 }
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index b9ca164..ee29f09 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -35,27 +35,28 @@
     ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
 }
 
-void DevicesFactoryHalAidl::onFirstRef() {
-    ALOGE("%s not implemented yet", __func__);
-}
-
 // Opens a device with the specified name. To close the device, it is
 // necessary to release references to the returned object.
 status_t DevicesFactoryHalAidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
     if (name == nullptr || device == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet %s", __func__, name);
-    return INVALID_OPERATION;
 
-    // TODO: only support primary now ("default" means "primary")
-    if (strcmp(name, "primary") != 0) {
-        auto serviceName = std::string() + IModule::descriptor + "/default";
-        auto service = IModule::fromBinder(
+    std::shared_ptr<IModule> service;
+    // FIXME: Normally we will list available HAL modules and connect to them,
+    // however currently we still get the list of module names from the config.
+    // Since the example service does not have all modules, the SM will wait
+    // for the missing ones forever.
+    if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0) {
+        if (strcmp(name, "primary") == 0) name = "default";
+        auto serviceName = std::string(IModule::descriptor) + "/" + name;
+        service = IModule::fromBinder(
                 ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
-        ALOGW("%s fromBinder %s %s", __func__, IModule::descriptor, service ? "succ" : "fail");
-        *device = new DeviceHalAidl(service);
+        ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
     }
+    // If the service is a nullptr, the device will not be really functional,
+    // but will not crash either.
+    *device = sp<DeviceHalAidl>::make(service);
     return OK;
 }
 
@@ -68,21 +69,25 @@
 }
 
 status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
-    if (callback == nullptr) {
-        return BAD_VALUE;
+    // Dynamic registration of module instances is not supported. The functionality
+    // in the audio server which is related to this callback can be removed together
+    // with HIDL support.
+    ALOG_ASSERT(callback != nullptr);
+    if (callback != nullptr) {
+        callback->onNewDevicesAvailable();
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    return NO_ERROR;
 }
 
 AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
     int32_t versionNumber = 0;
-    if (mIConfig) {
-        if (!mIConfig->getInterfaceVersion(&versionNumber).isOk()) {
-            ALOGE("%s getInterfaceVersion failed", __func__);
-        } else {
-            ALOGI("%s getInterfaceVersion %d", __func__, versionNumber);
+    if (mIConfig != 0) {
+        if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
+                !status.isOk()) {
+            ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
         }
+    } else {
+        ALOGW("%s no IConfig instance", __func__);
     }
     // AIDL does not have minor version, fill 0 for all versions
     return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index 71138a0..cb627bc 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -27,7 +27,6 @@
   public:
     explicit DevicesFactoryHalAidl(
             std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
-    void onFirstRef() override;
 
     // Opens a device with the specified name. To close the device, it is
     // necessary to release references to the returned object.
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index 3956a6c..ed952a3 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
-#define TIME_CHECK() auto timeCheck = \
-        mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
         : EffectConversionHelperHidl("EffectHalHidl"),
           mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
new file mode 100644
index 0000000..7338952
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -0,0 +1,511 @@
+/*
+ * 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 "StreamHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::IStreamCommon;
+using ::aidl::android::hardware::audio::core::IStreamIn;
+using ::aidl::android::hardware::audio::core::IStreamOut;
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+StreamHalAidl::StreamHalAidl(
+        std::string_view className, bool isInput, const StreamDescriptor& descriptor,
+        const std::shared_ptr<IStreamCommon>& stream)
+        : ConversionHelperAidl(className),
+          mIsInput(isInput),
+          mFrameSizeBytes(descriptor.frameSizeBytes),
+          mBufferSizeFrames(descriptor.bufferSizeFrames),
+          mCommandMQ(new CommandMQ(descriptor.command)),
+          mReplyMQ(new ReplyMQ(descriptor.reply)),
+          mDataMQ(maybeCreateDataMQ(descriptor)),
+          mStream(stream) {
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+            /* mStreamPowerLog.isUserDebugOrEngBuild() && */
+            StreamHalAidl::getAudioProperties(&config) == NO_ERROR) {
+        mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
+    }
+}
+
+StreamHalAidl::~StreamHalAidl() {
+    if (mStream != nullptr) {
+        ndk::ScopedAStatus status = mStream->close();
+        ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
+    }
+}
+
+status_t StreamHalAidl::getBufferSize(size_t *size) {
+    if (size == nullptr) {
+        return BAD_VALUE;
+    }
+    if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0) {
+        return NO_INIT;
+    }
+    *size = mFrameSizeBytes * mBufferSizeFrames;
+    return OK;
+}
+
+status_t StreamHalAidl::getAudioProperties(audio_config_base_t *configBase) {
+    if (configBase == nullptr) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    *configBase = AUDIO_CONFIG_BASE_INITIALIZER;
+    configBase->sample_rate = 48000;
+    configBase->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    configBase->channel_mask = mIsInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
+    // if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+    TIME_CHECK();
+    values->clear();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getFrameSize(size_t *size) {
+    if (size == nullptr) {
+        return BAD_VALUE;
+    }
+    if (mFrameSizeBytes == 0) {
+        return NO_INIT;
+    }
+    *size = mFrameSizeBytes;
+    return OK;
+}
+
+status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::standby() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::dump(int fd __unused, const Vector<String16>& args __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::start() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::stop() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
+                                  struct audio_mmap_buffer_info *info __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getMmapPosition(struct audio_mmap_position *position __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
+    mHalThreadPriority = priority;
+    return OK;
+}
+
+status_t StreamHalAidl::getHalPid(pid_t *pid __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
+    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
+        return true;
+    }
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
+                                               std::optional<audio_source_t> source __unused,
+                                               audio_devices_t type __unused) {
+    TIME_CHECK();
+    LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::legacyReleaseAudioPatch() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+namespace {
+
+/* Notes on callback ownership.
+
+This is how Binder ownership model looks like. The server implementation
+is owned by Binder framework (via sp<>). Proxies are owned by clients.
+When the last proxy disappears, Binder framework releases the server impl.
+
+Thus, it is not needed to keep any references to StreamCallback (this is
+the server impl) -- it will live as long as HAL server holds a strong ref to
+IStreamCallback proxy.
+
+The callback only keeps a weak reference to the stream. The stream is owned
+by AudioFlinger.
+
+*/
+
+class StreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback {
+    ndk::ScopedAStatus onTransferReady() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onError() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onDrainReady() override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+}  // namespace
+
+StreamOutHalAidl::StreamOutHalAidl(
+        const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
+        : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor,
+                nullptr /* FIXME: Retrieve IStreamCommon */),
+          mStream(stream) {}
+
+status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
+    TIME_CHECK();
+    *latency = 0;
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::write(
+        const void *buffer __unused, size_t bytes __unused, size_t *written __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    *written = 0;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::supportsPauseAndResume(
+        bool *supportsPause __unused, bool *supportsResume __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::pause() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::resume() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::supportsDrain(bool *supportsDrain __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::drain(bool earlyNotify __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::flush() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getPresentationPosition(
+        uint64_t *frames __unused, struct timespec *timestamp __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::updateSourceMetadata(
+        const StreamOutHalInterface::SourceMetadata& sourceMetadata __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getPlaybackRateParameters(
+        audio_playback_rate_t* playbackRate __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setPlaybackRateParameters(
+        const audio_playback_rate_t& playbackRate __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setEventCallback(
+        const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
+    return INVALID_OPERATION;
+}
+
+namespace {
+
+struct StreamOutEventCallback {
+    StreamOutEventCallback(const wp<StreamOutHalAidl>& stream) : mStream(stream) {}
+  private:
+    wp<StreamOutHalAidl> mStream;
+};
+
+}  // namespace
+
+status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
+    return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::getRecommendedLatencyModes(
+        std::vector<audio_latency_mode_t> *modes __unused) {
+    return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::setLatencyModeCallback(
+        const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
+    return INVALID_OPERATION;
+};
+
+void StreamOutHalAidl::onWriteReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onWriteReady");
+    callback->onWriteReady();
+}
+
+void StreamOutHalAidl::onDrainReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onDrainReady");
+    callback->onDrainReady();
+}
+
+void StreamOutHalAidl::onError() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onError");
+    callback->onError();
+}
+
+void StreamOutHalAidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs __unused) {
+    sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
+    if (callback == nullptr) return;
+    ALOGV("asyncCodecFormatCallback %s", __func__);
+    callback->onCodecFormatChanged(metadataBs);
+}
+
+void StreamOutHalAidl::onRecommendedLatencyModeChanged(
+        const std::vector<audio_latency_mode_t>& modes __unused) {
+    sp<StreamOutHalInterfaceLatencyModeCallback> callback = mLatencyModeCallback.load().promote();
+    if (callback == nullptr) return;
+    callback->onRecommendedLatencyModeChanged(modes);
+}
+
+status_t StreamOutHalAidl::exit() {
+    // FIXME this is using hard-coded strings but in the future, this functionality will be
+    //       converted to use audio HAL extensions required to support tunneling
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+StreamInHalAidl::StreamInHalAidl(
+        const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
+        : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor,
+                nullptr /* FIXME: Retrieve IStreamCommon */),
+          mStream(stream) {}
+
+status_t StreamInHalAidl::setGain(float gain __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::read(
+        void *buffer __unused, size_t bytes __unused, size_t *read __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    // FIXME: Don't forget to update mPowerLog
+    return OK;
+}
+
+status_t StreamInHalAidl::getInputFramesLost(uint32_t *framesLost __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::getCapturePosition(int64_t *frames __unused, int64_t *time __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::updateSinkMetadata(
+        const StreamInHalInterface::SinkMetadata& sinkMetadata  __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
new file mode 100644
index 0000000..86f48f3
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -0,0 +1,276 @@
+/*
+ * 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 <memory>
+#include <string_view>
+
+#include <aidl/android/hardware/audio/core/BpStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BpStreamIn.h>
+#include <aidl/android/hardware/audio/core/BpStreamOut.h>
+#include <fmq/AidlMessageQueue.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
+
+#include "ConversionHelperAidl.h"
+#include "StreamPowerLog.h"
+
+namespace android {
+
+class DeviceHalAidl;
+
+class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
+  public:
+    // Return size of input/output buffer in bytes for this stream - eg. 4800.
+    status_t getBufferSize(size_t *size) override;
+
+    // Return the base configuration of the stream:
+    //   - channel mask;
+    //   - format - e.g. AUDIO_FORMAT_PCM_16_BIT;
+    //   - sampling rate in Hz - eg. 44100.
+    status_t getAudioProperties(audio_config_base_t *configBase) override;
+
+    // Set audio stream parameters.
+    status_t setParameters(const String8& kvPairs) override;
+
+    // Get audio stream parameters.
+    status_t getParameters(const String8& keys, String8 *values) override;
+
+    // Return the frame size (number of bytes per sample) of a stream.
+    status_t getFrameSize(size_t *size) override;
+
+    // Add or remove the effect on the stream.
+    status_t addEffect(sp<EffectHalInterface> effect) override;
+    status_t removeEffect(sp<EffectHalInterface> effect) override;
+
+    // Put the audio hardware input/output into standby mode.
+    status_t standby() override;
+
+    status_t dump(int fd, const Vector<String16>& args) override;
+
+    // Start a stream operating in mmap mode.
+    status_t start() override;
+
+    // Stop a stream operating in mmap mode.
+    status_t stop() override;
+
+    // Retrieve information on the data buffer in mmap mode.
+    status_t createMmapBuffer(int32_t minSizeFrames,
+            struct audio_mmap_buffer_info *info) override;
+
+    // Get current read/write position in the mmap buffer
+    status_t getMmapPosition(struct audio_mmap_position *position) override;
+
+    // Set the priority of the thread that interacts with the HAL
+    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+    status_t setHalThreadPriority(int priority) override;
+
+    status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+            std::optional<audio_source_t> source,
+            audio_devices_t type) override;
+
+    status_t legacyReleaseAudioPatch() override;
+
+  protected:
+    typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command,
+          ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ;
+    typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ;
+    typedef AidlMessageQueue<int8_t,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
+
+    // Subclasses can not be constructed directly by clients.
+    StreamHalAidl(std::string_view className,
+            bool isInput,
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
+
+    ~StreamHalAidl() override;
+
+    status_t getHalPid(pid_t *pid);
+
+    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+
+    const bool mIsInput;
+    const size_t mFrameSizeBytes;
+    const size_t mBufferSizeFrames;
+    const std::unique_ptr<CommandMQ> mCommandMQ;
+    const std::unique_ptr<ReplyMQ> mReplyMQ;
+    const std::unique_ptr<DataMQ> mDataMQ;
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
+  private:
+    static std::unique_ptr<DataMQ> maybeCreateDataMQ(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
+        using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
+        if (descriptor.audio.getTag() == Tag::fmq) {
+            return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
+        }
+        return nullptr;
+    }
+
+    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
+    int mHalThreadPriority = HAL_THREAD_PRIORITY_DEFAULT;
+};
+
+class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
+  public:
+    // Return the audio hardware driver estimated latency in milliseconds.
+    status_t getLatency(uint32_t *latency) override;
+
+    // Use this method in situations where audio mixing is done in the hardware.
+    status_t setVolume(float left, float right) override;
+
+    // Selects the audio presentation (if available).
+    status_t selectPresentation(int presentationId, int programId) override;
+
+    // Write audio buffer to driver.
+    status_t write(const void *buffer, size_t bytes, size_t *written) override;
+
+    // Return the number of audio frames written by the audio dsp to DAC since
+    // the output has exited standby.
+    status_t getRenderPosition(uint32_t *dspFrames) override;
+
+    // Get the local time at which the next write to the audio driver will be presented.
+    status_t getNextWriteTimestamp(int64_t *timestamp) override;
+
+    // Set the callback for notifying completion of non-blocking write and drain.
+    status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
+
+    // Returns whether pause and resume operations are supported.
+    status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override;
+
+    // Notifies to the audio driver to resume playback following a pause.
+    status_t pause() override;
+
+    // Notifies to the audio driver to resume playback following a pause.
+    status_t resume() override;
+
+    // Returns whether drain operation is supported.
+    status_t supportsDrain(bool *supportsDrain) override;
+
+    // Requests notification when data buffered by the driver/hardware has been played.
+    status_t drain(bool earlyNotify) override;
+
+    // Notifies to the audio driver to flush the queued data.
+    status_t flush() override;
+
+    // Return a recent count of the number of audio frames presented to an external observer.
+    status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
+
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+    // Returns the Dual Mono mode presentation setting.
+    status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override;
+
+    // Sets the Dual Mono mode presentation on the output device.
+    status_t setDualMonoMode(audio_dual_mono_mode_t mode) override;
+
+    // Returns the Audio Description Mix level in dB.
+    status_t getAudioDescriptionMixLevel(float* leveldB) override;
+
+    // Sets the Audio Description Mix level in dB.
+    status_t setAudioDescriptionMixLevel(float leveldB) override;
+
+    // Retrieves current playback rate parameters.
+    status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override;
+
+    // Sets the playback rate parameters that control playback behavior.
+    status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override;
+
+    status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override;
+
+    status_t setLatencyMode(audio_latency_mode_t mode) override;
+    status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override;
+    status_t setLatencyModeCallback(
+            const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override;
+
+    void onRecommendedLatencyModeChanged(const std::vector<audio_latency_mode_t>& modes);
+
+    status_t exit() override;
+
+    void onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs);
+
+    // Methods used by StreamOutCallback ().
+    // FIXME: Consider the required visibility.
+    void onWriteReady();
+    void onDrainReady();
+    void onError();
+
+  private:
+    friend class sp<StreamOutHalAidl>;
+
+    mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+    mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+    mediautils::atomic_wp<StreamOutHalInterfaceLatencyModeCallback> mLatencyModeCallback;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
+
+    // Can not be constructed directly by clients.
+    StreamOutHalAidl(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream);
+
+    ~StreamOutHalAidl() override = default;
+};
+
+class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
+  public:
+    // Set the input gain for the audio driver.
+    status_t setGain(float gain) override;
+
+    // Read audio buffer in from driver.
+    status_t read(void *buffer, size_t bytes, size_t *read) override;
+
+    // Return the amount of input frames lost in the audio driver.
+    status_t getInputFramesLost(uint32_t *framesLost) override;
+
+    // Return a recent count of the number of audio frames received and
+    // the clock time associated with that frame count.
+    status_t getCapturePosition(int64_t *frames, int64_t *time) override;
+
+    // Get active microphones
+    status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) override;
+
+    // Set microphone direction (for processing)
+    status_t setPreferredMicrophoneDirection(
+                            audio_microphone_direction_t direction) override;
+
+    // Set microphone zoom (for processing)
+    status_t setPreferredMicrophoneFieldDimension(float zoom) override;
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+  private:
+    friend class sp<StreamInHalAidl>;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
+
+    // Can not be constructed directly by clients.
+    StreamInHalAidl(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
+
+    ~StreamInHalAidl() override = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 76f9a60..2c289e1 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
-#define TIME_CHECK() auto TimeCheck = \
-       mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 StreamHalHidl::StreamHalHidl(std::string_view className, IStream *stream)
         : CoreConversionHelperHidl(className),
           mStream(stream),
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 2c8219e..094b415 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -106,16 +106,10 @@
     virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port* port) {
-        ALOGE("%s override me port %p", __func__, port);
-        return OK;
-    }
+    virtual status_t getAudioPort(struct audio_port* port) = 0;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port_v7 *port) {
-        ALOGE("%s override me port %p", __func__, port);
-        return OK;
-    }
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 6823f4f..65b2c52 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -283,7 +283,7 @@
 }
 
 // Automatically create a TimeCheck class for a class and method.
-// This is used for Audio HIDL support.
+// This is used for Audio HAL support.
 mediautils::TimeCheck makeTimeCheckStatsForClassMethod(
         std::string_view className, std::string_view methodName) {
     std::shared_ptr<MethodStatistics<std::string>> statistics =
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index bdb5337..0823669 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -148,4 +148,9 @@
 TimeCheck makeTimeCheckStatsForClassMethod(
         std::string_view className, std::string_view methodName);
 
+// A handy statement-like macro to put at the beginning of almost every method
+// which calls into HAL. Note that it requires the class to implement 'getClassName'.
+#define TIME_CHECK() auto timeCheck = \
+            mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
 }  // namespace android::mediautils