Add libAudioHal AIDL interface placeholder
Add cpp backend only and ndk backend only conversion.
Add placeholder for DeviceHalInterface and EffectHalInterface.
Add several EffectHalInterface test cases to help testing.
Bug: 261129656
Test: Flash to Cuttlefish and run cts
Test: Flash to Panther and run audio use cases.
Change-Id: Ieaf5d7d72bd7d3e1897964b7abe211456766f443
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index bb5601f..d151817 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -241,15 +241,34 @@
"libaudiohal_default",
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_audio_core_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_hardware_audio_effect_ndk_static",
+ "latest_android_media_audio_common_types_ndk_shared",
],
srcs: [
"DevicesFactoryHalEntry.cpp",
"DevicesFactoryHalAidl.cpp",
+ "EffectBufferHalAidl.cpp",
+ "EffectHalAidl.cpp",
"EffectsFactoryHalAidl.cpp",
"EffectsFactoryHalEntry.cpp",
],
+ static_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ ],
shared_libs: [
"libbinder_ndk",
- ]
+ "libaudio_aidl_conversion_common_ndk",
+ ],
+ header_libs: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ "libaudio_system_headers",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wthread-safety",
+ "-DBACKEND_NDK",
+ ],
}
\ No newline at end of file
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
new file mode 100644
index 0000000..d85d960
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DeviceHalAidl"
+
+#include "DeviceHalAidl.h"
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t* devices) {
+ ALOGE("%s not implemented yet devices %p", __func__, devices);
+ return OK;
+}
+
+status_t DeviceHalAidl::initCheck() {
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::setVoiceVolume(float volume) {
+ mVoiceVolume = volume;
+ ALOGE("%s not implemented yet %f", __func__, volume);
+ return OK;
+}
+
+status_t DeviceHalAidl::setMasterVolume(float volume) {
+ mMasterVolume = volume;
+ ALOGE("%s not implemented yet %f", __func__, volume);
+ return OK;
+}
+
+status_t DeviceHalAidl::getMasterVolume(float *volume) {
+ *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);
+ return OK;
+}
+
+status_t DeviceHalAidl::setMicMute(bool state) {
+ mMicMute = state;
+ ALOGE("%s not implemented yet %d", __func__, state);
+ return OK;
+}
+status_t DeviceHalAidl::getMicMute(bool *state) {
+ *state = mMicMute;
+ ALOGE("%s not implemented yet %d", __func__, *state);
+ return OK;
+}
+status_t DeviceHalAidl::setMasterMute(bool state) {
+ mMasterMute = state;
+ ALOGE("%s not implemented yet %d", __func__, state);
+ return OK;
+}
+status_t DeviceHalAidl::getMasterMute(bool *state) {
+ *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());
+ 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());
+ return OK;
+}
+
+status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
+ ALOGE("%s not implemented yet %p %zu", __func__, config, *size);
+ 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);
+ 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);
+ return OK;
+}
+
+status_t DeviceHalAidl::supportsAudioPatches(bool* supportsPatches) {
+ *supportsPatches = true;
+ 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);
+ return OK;
+}
+
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
+ ALOGE("%s not implemented yet patch %d", __func__, patch);
+ return OK;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
+ ALOGE("%s not implemented yet config %p", __func__, config);
+ return OK;
+}
+
+status_t DeviceHalAidl::getMicrophones(
+ std::vector<audio_microphone_characteristic_t>* microphones) {
+ ALOGE("%s not implemented yet microphones %p", __func__, microphones);
+ return OK;
+}
+
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) {
+ if (!effect) {
+ return BAD_VALUE;
+ }
+ ALOGE("%s not implemented yet device %d", __func__, device);
+ return OK;
+}
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device,
+ sp<EffectHalInterface> effect) {
+ if (!effect) {
+ return BAD_VALUE;
+ }
+ ALOGE("%s not implemented yet device %d", __func__, device);
+ return OK;
+}
+
+status_t DeviceHalAidl::getMmapPolicyInfos(
+ media::audio::common::AudioMMapPolicyType policyType __unused,
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+ ALOGE("%s not implemented yet", __func__);
+ return base::unexpected(INVALID_OPERATION);
+}
+
+status_t DeviceHalAidl::dump(int __unused, const Vector<String16>& __unused) {
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+};
+
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) override {
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
new file mode 100644
index 0000000..5e8a8dd
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <media/audiohal/DeviceHalInterface.h>
+#include <media/audiohal/EffectHalInterface.h>
+
+#include <aidl/android/hardware/audio/core/BpModule.h>
+
+namespace android {
+
+class DeviceHalAidl : public DeviceHalInterface {
+ 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;
+
+ // Check to see if the audio hardware interface has been initialized.
+ status_t initCheck() override;
+
+ // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+ status_t setVoiceVolume(float volume) override;
+
+ // Set the audio volume for all audio activities other than voice call.
+ status_t setMasterVolume(float volume) override;
+
+ // Get the current master volume value for the HAL.
+ status_t getMasterVolume(float *volume) override;
+
+ // Called when the audio mode changes.
+ status_t setMode(audio_mode_t mode) override;
+
+ // Muting control.
+ status_t setMicMute(bool state) override;
+
+ status_t getMicMute(bool* state) override;
+
+ status_t setMasterMute(bool state) override;
+
+ status_t getMasterMute(bool *state) override;
+
+ // Set global audio parameters.
+ status_t setParameters(const String8& kvPairs) override;
+
+ // Get global audio parameters.
+ status_t getParameters(const String8& keys, String8 *values) override;
+
+ // Returns audio input buffer size according to parameters passed.
+ status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
+
+ // Creates and opens the audio hardware output stream. The stream is closed
+ // by releasing all references to the returned object.
+ status_t 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) override;
+
+ // Creates and opens the audio hardware input stream. The stream is closed
+ // by releasing all references to the returned object.
+ status_t 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) override;
+
+ // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+ status_t supportsAudioPatches(bool* supportsPatches) override;
+
+ // Creates an audio patch between several source and sink ports.
+ status_t 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) override;
+
+ // Releases an audio patch.
+ status_t releaseAudioPatch(audio_patch_handle_t patch) override;
+
+ // Set audio port configuration.
+ status_t setAudioPortConfig(const struct audio_port_config* config) override;
+
+ // List microphones
+ status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones);
+
+ status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+ status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+ status_t getMmapPolicyInfos(media::audio::common::AudioMMapPolicyType policyType __unused,
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos
+ __unused) override;
+
+ int32_t getAAudioMixerBurstCount() override;
+
+ int32_t getAAudioHardwareBurstMinUsec() override;
+
+ error::Result<audio_hw_sync_t> getHwAvSync() override;
+
+ status_t dump(int __unused, const Vector<String16>& __unused) override;
+
+ int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
+
+ private:
+ friend class DevicesFactoryHalAidl;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mCore;
+ float mMasterVolume = 0.0f;
+ float mVoiceVolume = 0.0f;
+ bool mMasterMute = false;
+ bool mMicMute = false;
+
+ // Can not be constructed directly by clients.
+ explicit DeviceHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& core)
+ : mCore(core) {}
+
+ // The destructor automatically closes the device.
+ ~DeviceHalAidl();
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 0cdf621..be063ab 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -459,12 +459,13 @@
#if MAJOR_VERSION == 2
status_t DeviceHalHidl::getMicrophones(
- std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+ std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
if (mDevice == 0) return NO_INIT;
return INVALID_OPERATION;
}
#elif MAJOR_VERSION >= 4
-status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+status_t DeviceHalHidl::getMicrophones(
+ std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
@@ -475,8 +476,7 @@
audio_microphone_characteristic_t dst;
//convert
(void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
- media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
- microphonesInfo->push_back(microphone);
+ microphonesInfo->push_back(dst);
}
});
return processReturn("getMicrophones", ret, retval);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 3e33609..052eb65 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -30,87 +30,74 @@
{
public:
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
- virtual status_t getSupportedDevices(uint32_t *devices);
+ status_t getSupportedDevices(uint32_t *devices) override;
// Check to see if the audio hardware interface has been initialized.
- virtual status_t initCheck();
+ status_t initCheck() override;
// Set the audio volume of a voice call. Range is between 0.0 and 1.0.
- virtual status_t setVoiceVolume(float volume);
+ status_t setVoiceVolume(float volume) override;
// Set the audio volume for all audio activities other than voice call.
- virtual status_t setMasterVolume(float volume);
+ status_t setMasterVolume(float volume) override;
// Get the current master volume value for the HAL.
- virtual status_t getMasterVolume(float *volume);
+ status_t getMasterVolume(float *volume) override;
// Called when the audio mode changes.
- virtual status_t setMode(audio_mode_t mode);
+ status_t setMode(audio_mode_t mode) override;
// Muting control.
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool *state);
- virtual status_t setMasterMute(bool state);
- virtual status_t getMasterMute(bool *state);
+ status_t setMicMute(bool state) override;
+ status_t getMicMute(bool *state) override;
+ status_t setMasterMute(bool state) override;
+ status_t getMasterMute(bool *state) override;
// Set global audio parameters.
- virtual status_t setParameters(const String8& kvPairs);
+ status_t setParameters(const String8& kvPairs) override;
// Get global audio parameters.
- virtual status_t getParameters(const String8& keys, String8 *values);
+ status_t getParameters(const String8& keys, String8 *values) override;
// Returns audio input buffer size according to parameters passed.
- virtual status_t getInputBufferSize(const struct audio_config *config,
- size_t *size);
+ status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
// Creates and opens the audio hardware output stream. The stream is closed
// by releasing all references to the returned object.
- virtual status_t 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);
+ status_t 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) override;
// Creates and opens the audio hardware input stream. The stream is closed
// by releasing all references to the returned object.
- virtual status_t 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);
+ status_t 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) override;
// Returns whether createAudioPatch and releaseAudioPatch operations are supported.
- virtual status_t supportsAudioPatches(bool *supportsPatches);
+ status_t supportsAudioPatches(bool* supportsPatches) override;
// Creates an audio patch between several source and sink ports.
- virtual status_t 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);
+ status_t 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) override;
// Releases an audio patch.
- virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+ status_t releaseAudioPatch(audio_patch_handle_t patch) override;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port *port);
+ status_t getAudioPort(struct audio_port *port) override;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port_v7 *port);
+ status_t getAudioPort(struct audio_port_v7 *port) override;
// Set audio port configuration.
- virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+ status_t setAudioPortConfig(const struct audio_port_config *config) override;
// List microphones
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones) override;
status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 29fb558..b9ca164 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -17,18 +17,22 @@
#define LOG_TAG "DevicesFactoryHalAidl"
//#define LOG_NDEBUG 0
+#include <aidl/android/hardware/audio/core/IModule.h>
#include <android/binder_manager.h>
+#include <memory>
#include <utils/Log.h>
+#include "DeviceHalAidl.h"
#include "DevicesFactoryHalAidl.h"
+using namespace ::aidl::android::hardware::audio::core;
using ::android::detail::AudioHalVersionInfo;
namespace android {
-DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig) {
+DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
+ : mIConfig(std::move(iconfig)) {
ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
- mIConfig = std::move(iconfig);
}
void DevicesFactoryHalAidl::onFirstRef() {
@@ -41,8 +45,18 @@
if (name == nullptr || device == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
+ 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(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ ALOGW("%s fromBinder %s %s", __func__, IModule::descriptor, service ? "succ" : "fail");
+ *device = new DeviceHalAidl(service);
+ }
+ return OK;
}
status_t DevicesFactoryHalAidl::getHalPids(std::vector<pid_t> *pids) {
@@ -76,9 +90,14 @@
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
+ auto serviceName = std::string(IConfig::descriptor) + "/default";
auto service = IConfig::fromBinder(
- ndk::SpAIBinder(AServiceManager_waitForService(IConfig::descriptor)));
- return service ? new DevicesFactoryHalAidl(service) : nullptr;
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ if (!service) {
+ ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+ return nullptr;
+ }
+ return new DevicesFactoryHalAidl(service);
}
} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index f4812af..71138a0 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -20,14 +20,13 @@
#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <utils/RefBase.h>
-using namespace ::aidl::android::hardware::audio::core;
-
namespace android {
class DevicesFactoryHalAidl : public DevicesFactoryHalInterface
{
public:
- explicit DevicesFactoryHalAidl(std::shared_ptr<IConfig> iConfig);
+ 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
@@ -41,8 +40,8 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
private:
- std::shared_ptr<IConfig> mIConfig;
- virtual ~DevicesFactoryHalAidl() = default;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mIConfig;
+ ~DevicesFactoryHalAidl() = default;
};
} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.cpp b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
new file mode 100644
index 0000000..5af8e24
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectBufferHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "EffectBufferHalAidl.h"
+
+namespace android {
+namespace effect {
+
+// static
+status_t EffectBufferHalAidl::allocate(size_t size, sp<EffectBufferHalInterface>* buffer) {
+ ALOGE("%s not implemented yet %zu %p", __func__, size, buffer);
+ return mirror(nullptr, size, buffer);
+}
+
+status_t EffectBufferHalAidl::mirror(void* external, size_t size,
+ sp<EffectBufferHalInterface>* buffer) {
+ // buffer->setExternalData(external);
+ ALOGW("%s not implemented yet %p %zu %p", __func__, external, size, buffer);
+ return OK;
+}
+
+EffectBufferHalAidl::EffectBufferHalAidl(size_t size)
+ : mBufferSize(size),
+ mFrameCountChanged(false),
+ mExternalData(nullptr),
+ mAudioBuffer{0, {nullptr}} {
+}
+
+EffectBufferHalAidl::~EffectBufferHalAidl() {
+}
+
+status_t EffectBufferHalAidl::init() {
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+audio_buffer_t* EffectBufferHalAidl::audioBuffer() {
+ return &mAudioBuffer;
+}
+
+void* EffectBufferHalAidl::externalData() const {
+ return mExternalData;
+}
+
+void EffectBufferHalAidl::setFrameCount(size_t frameCount) {
+ mAudioBuffer.frameCount = frameCount;
+ mFrameCountChanged = true;
+}
+
+bool EffectBufferHalAidl::checkFrameCountChange() {
+ bool result = mFrameCountChanged;
+ mFrameCountChanged = false;
+ return result;
+}
+
+void EffectBufferHalAidl::setExternalData(void* external) {
+ mExternalData = external;
+}
+
+void EffectBufferHalAidl::update() {
+ ALOGW("%s not implemented yet", __func__);
+}
+
+void EffectBufferHalAidl::commit() {
+ ALOGW("%s not implemented yet", __func__);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.h b/media/libaudiohal/impl/EffectBufferHalAidl.h
new file mode 100644
index 0000000..f488708
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <media/audiohal/EffectBufferHalInterface.h>
+#include <system/audio_effect.h>
+
+namespace android {
+namespace effect {
+
+class EffectBufferHalAidl : public EffectBufferHalInterface {
+ public:
+ static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
+ static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
+
+ audio_buffer_t* audioBuffer() override;
+ void* externalData() const override;
+
+ size_t getSize() const override { return mBufferSize; }
+
+ void setExternalData(void* external) override;
+ void setFrameCount(size_t frameCount) override;
+ bool checkFrameCountChange() override;
+
+ void update() override;
+ void commit() override;
+ void update(size_t size) override;
+ void commit(size_t size) override;
+
+ private:
+ friend class EffectBufferHalInterface;
+
+ const size_t mBufferSize;
+ bool mFrameCountChanged;
+ void* mExternalData;
+ audio_buffer_t mAudioBuffer;
+
+ // Can not be constructed directly by clients.
+ explicit EffectBufferHalAidl(size_t size);
+
+ ~EffectBufferHalAidl();
+
+ status_t init();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
new file mode 100644
index 0000000..31c5ca5
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <media/audiohal/AudioHalUtils.h>
+#include <media/EffectsFactoryApi.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "EffectHalAidl.h"
+
+#include <system/audio.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::hardware::audio::effect::State;
+using ::aidl::android::hardware::audio::effect::Parameter;
+
+namespace android {
+namespace effect {
+
+EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
+ int32_t sessionId, int32_t ioId)
+ : mEffectId(effectId), mSessionId(sessionId), mIoId(ioId), mEffect(effect) {}
+
+EffectHalAidl::~EffectHalAidl() {}
+
+status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::process() {
+ ALOGW("%s not implemented yet", __func__);
+ // write to input FMQ here?
+ return OK;
+}
+
+// TODO: no one using, maybe deprecate this interface
+status_t EffectHalAidl::processReverse() {
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || replySize == NULL ||
+ *replySize != sizeof(int32_t) || pReplyData == NULL) {
+ ALOGE("%s parameter error code %u", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+
+ *static_cast<int32_t*>(pReplyData) = FAILED_TRANSACTION;
+ memcpy(&mConfig, pCmdData, cmdSize);
+
+ State state;
+ RETURN_IF_BINDER_FAIL(mEffect->getState(&state));
+ // effect not open yet, save settings locally
+ if (state != State::INIT) {
+ effect_config_t* legacyConfig = static_cast<effect_config_t*>(pCmdData);
+ // already open, apply latest settings
+ Parameter aidlParam;
+ Parameter::Common aidlCommon;
+ aidlCommon.input.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
+ legacyConfig->inputCfg, true /* isInput */));
+ aidlCommon.output.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
+ legacyConfig->outputCfg, false /* isInput */));
+ aidlCommon.session = mSessionId;
+ aidlCommon.ioHandle = mIoId;
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ aidlParam.set<Parameter::common>(aidlCommon);
+ RETURN_IF_BINDER_FAIL(mEffect->setParameter(aidlParam));
+ }
+ *(int*)pReplyData = 0;
+ *static_cast<int32_t*>(pReplyData) = OK;
+ return OK;
+}
+
+status_t EffectHalAidl::handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+ *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+ ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+
+ *(effect_config_t*)pReplyData = mConfig;
+ return OK;
+}
+
+status_t EffectHalAidl::handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ ALOGW("%s not implemented yet", __func__);
+ if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+ *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+ ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+status_t EffectHalAidl::handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ ALOGW("%s not implemented yet", __func__);
+ if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+ *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+ ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ ALOGW("%s code %d not implemented yet", __func__, cmdCode);
+ ::ndk::ScopedAStatus status;
+ switch (cmdCode) {
+ case EFFECT_CMD_INIT: {
+ // open with default effect_config_t (convert to Parameter.Common)
+ IEffect::OpenEffectReturn ret;
+ Parameter::Common common;
+ RETURN_IF_BINDER_FAIL(mEffect->open(common, std::nullopt, &ret));
+ return OK;
+ }
+ case EFFECT_CMD_SET_CONFIG:
+ return handleSetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ case EFFECT_CMD_GET_CONFIG:
+ return handleGetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ case EFFECT_CMD_RESET:
+ return mEffect->command(CommandId::RESET).getStatus();
+ case EFFECT_CMD_ENABLE:
+ return mEffect->command(CommandId::START).getStatus();
+ case EFFECT_CMD_DISABLE:
+ return mEffect->command(CommandId::STOP).getStatus();
+ case EFFECT_CMD_SET_PARAM:
+ return handleSetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ case EFFECT_CMD_SET_PARAM_DEFERRED:
+ case EFFECT_CMD_SET_PARAM_COMMIT:
+ // TODO
+ return OK;
+ case EFFECT_CMD_GET_PARAM:
+ return handleGetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ case EFFECT_CMD_SET_DEVICE:
+ return OK;
+ case EFFECT_CMD_SET_VOLUME:
+ return OK;
+ case EFFECT_CMD_SET_AUDIO_MODE:
+ return OK;
+ case EFFECT_CMD_SET_CONFIG_REVERSE:
+ return OK;
+ case EFFECT_CMD_SET_INPUT_DEVICE:
+ return OK;
+ case EFFECT_CMD_GET_CONFIG_REVERSE:
+ return OK;
+ case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS:
+ return OK;
+ case EFFECT_CMD_GET_FEATURE_CONFIG:
+ return OK;
+ case EFFECT_CMD_SET_FEATURE_CONFIG:
+ return OK;
+ case EFFECT_CMD_SET_AUDIO_SOURCE:
+ return OK;
+ case EFFECT_CMD_OFFLOAD:
+ return OK;
+ case EFFECT_CMD_DUMP:
+ return OK;
+ case EFFECT_CMD_FIRST_PROPRIETARY:
+ return OK;
+ default:
+ return INVALID_OPERATION;
+ }
+ return INVALID_OPERATION;
+}
+
+status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
+ ALOGW("%s %p", __func__, pDescriptor);
+ if (pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+ Descriptor aidlDesc;
+ RETURN_IF_BINDER_FAIL(mEffect->getDescriptor(&aidlDesc));
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
+ return OK;
+}
+
+status_t EffectHalAidl::close() {
+ auto ret = mEffect->close();
+ ALOGI("%s %s", __func__, ret.getMessage());
+ return ret.getStatus();
+}
+
+status_t EffectHalAidl::dump(int fd) {
+ ALOGW("%s not implemented yet, fd %d", __func__, fd);
+ return OK;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
new file mode 100644
index 0000000..76bb240
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <system/audio_effect.h>
+
+namespace android {
+namespace effect {
+
+class EffectHalAidl : public EffectHalInterface {
+ public:
+ // Set the input buffer.
+ status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+ // Set the output buffer.
+ status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+ // Effect process function.
+ status_t process() override;
+
+ // Process reverse stream function. This function is used to pass
+ // a reference stream to the effect engine.
+ status_t processReverse() override;
+
+ // Send a command and receive a response to/from effect engine.
+ status_t command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+ void* pReplyData) override;
+
+ // Returns the effect descriptor.
+ status_t getDescriptor(effect_descriptor_t *pDescriptor) override;
+
+ // Free resources on the remote side.
+ status_t close() override;
+
+ // Whether it's a local implementation.
+ bool isLocal() const override { return false; }
+
+ status_t dump(int fd) override;
+
+ uint64_t effectId() const override { return mEffectId; }
+
+ private:
+ friend class EffectsFactoryHalAidl;
+
+ const uint64_t mEffectId;
+ const int32_t mSessionId;
+ const int32_t mIoId;
+ sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
+ effect_config_t mConfig;
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+
+ // Can not be constructed directly by clients.
+ EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId);
+
+ status_t handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData);
+ status_t handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData);
+ status_t handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData);
+ status_t handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData);
+
+ // The destructor automatically releases the effect.
+ virtual ~EffectHalAidl();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 7aec859..0039c86 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -14,69 +14,122 @@
* limitations under the License.
*/
-#include <random>
+#include <algorithm>
+#include <cstdint>
+#include <memory>
#define LOG_TAG "EffectsFactoryHalAidl"
//#define LOG_NDEBUG 0
#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <android/binder_manager.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <media/audiohal/AudioHalUtils.h>
#include <utils/Log.h>
+#include "EffectBufferHalAidl.h"
+#include "EffectHalAidl.h"
#include "EffectsFactoryHalAidl.h"
using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::media::audio::common::AudioUuid;
using android::detail::AudioHalVersionInfo;
namespace android {
namespace effect {
-EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory) {
+EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory)
+ : mFactory(effectsFactory),
+ mHalVersion(AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, [this]() {
+ int32_t majorVersion = 0;
+ return (mFactory && mFactory->getInterfaceVersion(&majorVersion).isOk()) ? majorVersion
+ : 0;
+ }())) {
ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
- mEffectsFactory = effectsFactory;
}
status_t EffectsFactoryHalAidl::queryNumberEffects(uint32_t *pNumEffects) {
if (pNumEffects == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+
+ {
+ std::lock_guard lg(mLock);
+ RETURN_IF_NOT_OK(queryEffectList_l());
+ *pNumEffects = mDescList->size();
+ }
+ ALOGI("%s %d", __func__, *pNumEffects);
+ return OK;
}
status_t EffectsFactoryHalAidl::getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) {
- if (index < 0 || pDescriptor == nullptr) {
+ if (pDescriptor == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+
+ std::lock_guard lg(mLock);
+ RETURN_IF_NOT_OK(queryEffectList_l());
+
+ auto listSize = mDescList->size();
+ if (index >= listSize) {
+ ALOGE("%s index %d exceed size DescList %zd", __func__, index, listSize);
+ return INVALID_OPERATION;
+ }
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(mDescList->at(index)));
+ return OK;
}
-status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* pEffectUuid,
+status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* halUuid,
effect_descriptor_t* pDescriptor) {
- if (pEffectUuid == nullptr || pDescriptor == nullptr) {
+ if (halUuid == nullptr || pDescriptor == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+
+ AudioUuid uuid =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
+ std::lock_guard lg(mLock);
+ return getHalDescriptorWithImplUuid_l(uuid, pDescriptor);
}
-status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* pEffectType,
+status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* halType,
std::vector<effect_descriptor_t>* descriptors) {
- if (pEffectType == nullptr || descriptors == nullptr) {
+ if (halType == nullptr || descriptors == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+
+ AudioUuid type =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halType));
+ std::lock_guard lg(mLock);
+ return getHalDescriptorWithTypeUuid_l(type, descriptors);
}
-status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId,
+status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* uuid, int32_t sessionId,
int32_t ioId, int32_t deviceId __unused,
sp<EffectHalInterface>* effect) {
- if (pEffectUuid == nullptr || effect == nullptr) {
+ if (uuid == nullptr || effect == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet %d %d", __func__, sessionId, ioId);
- return INVALID_OPERATION;
+ ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
+
+ AudioUuid aidlUuid =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+ std::shared_ptr<IEffect> aidlEffect;
+ ndk::ScopedAStatus status = mFactory->createEffect(aidlUuid, &aidlEffect);
+ if (!status.isOk() || aidlEffect == nullptr) {
+ ALOGE("%s IFactory::createFactory failed %s UUID %s", __func__,
+ status.getDescription().c_str(), aidlUuid.toString().c_str());
+ return INVALID_OPERATION;
+ }
+ uint64_t effectId;
+ {
+ std::lock_guard lg(mLock);
+ effectId = ++mEffectIdCounter;
+ }
+
+ *effect = new EffectHalAidl(aidlEffect, effectId, sessionId, ioId);
+ return OK;
}
status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
@@ -85,33 +138,77 @@
}
status_t EffectsFactoryHalAidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
- if (size <= 0 || buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+ ALOGI("%s size %zu buffer %p", __func__, size, buffer);
+ // Buffer doesn't allocated here for AIDL, instead each effect open will return I/O data FMQ.
+ return EffectBufferHalAidl::allocate(size, buffer);
}
status_t EffectsFactoryHalAidl::mirrorBuffer(void* external, size_t size,
sp<EffectBufferHalInterface>* buffer) {
- if (external == nullptr || size <= 0 || buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+ ALOGI("%s extern %p size %zu buffer %p", __func__, external, size, buffer);
+ // TODO: implement with FMQ
+ return EffectBufferHalAidl::mirror(external, size, buffer);
}
AudioHalVersionInfo EffectsFactoryHalAidl::getHalVersion() const {
- int32_t versionNumber = 0;
- if (mEffectsFactory) {
- if (!mEffectsFactory->getInterfaceVersion(&versionNumber).isOk()) {
- ALOGE("%s getInterfaceVersion failed", __func__);
- } else {
- ALOGI("%s getInterfaceVersion %d", __func__, versionNumber);
+ return mHalVersion;
+}
+
+status_t EffectsFactoryHalAidl::queryEffectList_l() {
+ if (!mDescList) {
+ std::vector<Descriptor> list;
+ auto status = mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &list);
+ if (!status.isOk()) {
+ ALOGE("%s IFactory::queryEffects failed %s", __func__, status.getDescription().c_str());
+ return status.getStatus();
}
+
+ mDescList = std::make_unique<std::vector<Descriptor>>(list);
}
- // AIDL does not have minor version, fill 0 for all versions
- return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithImplUuid_l(const AudioUuid& uuid,
+ effect_descriptor_t* pDescriptor) {
+ if (pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+ if (!mDescList) {
+ RETURN_IF_NOT_OK(queryEffectList_l());
+ }
+
+ auto matchIt = std::find_if(mDescList->begin(), mDescList->end(),
+ [&](const auto& desc) { return desc.common.id.uuid == uuid; });
+ if (matchIt == mDescList->end()) {
+ ALOGE("%s UUID %s not found", __func__, uuid.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithTypeUuid_l(
+ const AudioUuid& type, std::vector<effect_descriptor_t>* descriptors) {
+ if (descriptors == nullptr) {
+ return BAD_VALUE;
+ }
+ if (!mDescList) {
+ RETURN_IF_NOT_OK(queryEffectList_l());
+ }
+ std::vector<Descriptor> result;
+ std::copy_if(mDescList->begin(), mDescList->end(), std::back_inserter(result),
+ [&](auto& desc) { return desc.common.id.type == type; });
+ if (result.size() == 0) {
+ ALOGE("%s type UUID %s not found", __func__, type.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ *descriptors = VALUE_OR_RETURN_STATUS(
+ aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
+ result, ::aidl::android::aidl2legacy_Descriptor_effect_descriptor));
+ return OK;
}
} // namespace effect
@@ -120,9 +217,14 @@
// exports from a static library are optimized out unless actually used by
// the shared library. See EffectsFactoryHalEntry.cpp.
extern "C" void* createIEffectsFactoryImpl() {
- auto factory = IFactory::fromBinder(
- ndk::SpAIBinder(AServiceManager_waitForService(IFactory::descriptor)));
- return factory ? new effect::EffectsFactoryHalAidl(factory) : nullptr;
+ auto serviceName = std::string(IFactory::descriptor) + "/default";
+ auto service = IFactory::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ if (!service) {
+ ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+ return nullptr;
+ }
+ return new effect::EffectsFactoryHalAidl(service);
}
} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index d6b5684..1e85da9 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -16,7 +16,13 @@
#pragma once
+#include <cstddef>
+#include <memory>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/thread_defs.h>
namespace android {
namespace effect {
@@ -40,8 +46,8 @@
std::vector<effect_descriptor_t>* descriptors) override;
// Creates an effect engine of the specified type.
- // To release the effect engine, it is necessary to release references
- // to the returned effect object.
+ // To release the effect engine, it is necessary to release references to the returned effect
+ // object.
status_t createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId, int32_t ioId,
int32_t deviceId, sp<EffectHalInterface>* effect) override;
@@ -51,11 +57,23 @@
status_t mirrorBuffer(void* external, size_t size,
sp<EffectBufferHalInterface>* buffer) override;
- android::detail::AudioHalVersionInfo getHalVersion() const override;
+ detail::AudioHalVersionInfo getHalVersion() const override;
private:
- std::shared_ptr<IFactory> mEffectsFactory;
+ std::mutex mLock;
+ const std::shared_ptr<IFactory> mFactory;
+ uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0; // Align with HIDL (0 is INVALID_ID)
+ std::unique_ptr<std::vector<Descriptor>> mDescList GUARDED_BY(mLock) = nullptr;
+ const detail::AudioHalVersionInfo mHalVersion;
+
virtual ~EffectsFactoryHalAidl() = default;
+ status_t queryEffectList_l() REQUIRES(mLock);
+ status_t getHalDescriptorWithImplUuid_l(
+ const aidl::android::media::audio::common::AudioUuid& uuid,
+ effect_descriptor_t* pDescriptor) REQUIRES(mLock);
+ status_t getHalDescriptorWithTypeUuid_l(
+ const aidl::android::media::audio::common::AudioUuid& type,
+ std::vector<effect_descriptor_t>* descriptors) REQUIRES(mLock);
};
} // namespace effect