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