Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6e0cd41 authored by Shunkai Yao's avatar Shunkai Yao Committed by Automerger Merge Worker
Browse files

Merge "Implement libAudioHal AIDL EffectsFactoryHalInterface getProcessings"...

Merge "Implement libAudioHal AIDL EffectsFactoryHalInterface getProcessings" into udc-dev am: 37f5d129 am: 107c9aa6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/23150195



Change-Id: Id9bffeb6a2355c378ca648af3eafb8c5ea9118e9
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents fd6ad12d 107c9aa6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -288,6 +288,11 @@ aidl2legacy_AudioOutputFlags_audio_output_flags_t(media::audio::common::AudioOut
ConversionResult<media::audio::common::AudioOutputFlags>
legacy2aidl_audio_output_flags_t_AudioOutputFlags(audio_output_flags_t legacy);

ConversionResult<audio_stream_type_t>
aidl2legacy_AudioStreamType_audio_stream_type_t(media::audio::common::AudioStreamType aidl);
ConversionResult<media::audio::common::AudioStreamType>
legacy2aidl_audio_stream_type_t_AudioStreamType(audio_stream_type_t legacy);

// This type is unnamed in the original definition, thus we name it here.
using audio_port_config_mix_ext_usecase = decltype(audio_port_config_mix_ext::usecase);
ConversionResult<audio_port_config_mix_ext_usecase>
+0 −5
Original line number Diff line number Diff line
@@ -72,11 +72,6 @@ status_t legacy2aidl_audio_port_config_device_ext_AudioPortDeviceExt(
        media::audio::common::AudioPortDeviceExt* aidl,
        media::AudioPortDeviceExtSys* aidlDeviceExt);

ConversionResult<audio_stream_type_t> aidl2legacy_AudioStreamType_audio_stream_type_t(
        media::audio::common::AudioStreamType aidl);
ConversionResult<media::audio::common::AudioStreamType>
legacy2aidl_audio_stream_type_t_AudioStreamType(audio_stream_type_t legacy);

ConversionResult<audio_port_config_mix_ext> aidl2legacy_AudioPortMixExt(
        const media::audio::common::AudioPortMixExt& aidl, media::AudioPortRole role,
        const media::AudioPortMixExtSys& aidlMixExt);
+79 −7
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Processing;
using ::aidl::android::media::audio::common::AudioSource;
using ::aidl::android::media::audio::common::AudioStreamType;
using ::aidl::android::media::audio::common::AudioUuid;
using ::android::base::unexpected;
using ::android::detail::AudioHalVersionInfo;
@@ -96,7 +98,13 @@ EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFa
          return list;
      }()),
      mEffectCount(mNonProxyDescList.size() + mProxyDescList.size()),
      mEffectProcessings(nullptr /* TODO: add AIDL implementation */) {
      mAidlProcessings([this]() -> std::vector<Processing> {
          std::vector<Processing> processings;
          if (!mFactory || !mFactory->queryProcessing(std::nullopt, &processings).isOk()) {
              ALOGE("%s queryProcessing failed", __func__);
          }
          return processings;
      }()) {
    ALOG_ASSERT(mFactory != nullptr, "Provided IEffectsFactory service is NULL");
    ALOGI("%s with %zu nonProxyEffects and %zu proxyEffects", __func__, mNonProxyDescList.size(),
          mProxyDescList.size());
@@ -274,15 +282,79 @@ bool EffectsFactoryHalAidl::isProxyEffect(const AudioUuid& uuid) const {
}

std::shared_ptr<const effectsConfig::Processings> EffectsFactoryHalAidl::getProcessings() const {
    return mEffectProcessings;

    auto getConfigEffectWithDescriptor =
            [](const auto& desc) -> std::shared_ptr<const effectsConfig::Effect> {
        effectsConfig::Effect effect = {.name = desc.common.name, .isProxy = false};
        if (const auto uuid =
                    ::aidl::android::aidl2legacy_AudioUuid_audio_uuid_t(desc.common.id.uuid);
            uuid.ok()) {
            static_cast<effectsConfig::EffectImpl>(effect).uuid = uuid.value();
            return std::make_shared<const effectsConfig::Effect>(effect);
        } else {
            return nullptr;
        }
    };

    auto getConfigProcessingWithAidlProcessing =
            [&](const auto& aidlProcess, std::vector<effectsConfig::InputStream>& preprocess,
                std::vector<effectsConfig::OutputStream>& postprocess) {
                if (aidlProcess.type.getTag() == Processing::Type::streamType) {
                    AudioStreamType aidlType =
                            aidlProcess.type.template get<Processing::Type::streamType>();
                    const auto type =
                            ::aidl::android::aidl2legacy_AudioStreamType_audio_stream_type_t(
                                    aidlType);
                    if (!type.ok()) {
                        return;
                    }

                    std::vector<std::shared_ptr<const effectsConfig::Effect>> effects;
                    std::transform(aidlProcess.ids.begin(), aidlProcess.ids.end(),
                                   std::back_inserter(effects), getConfigEffectWithDescriptor);
                    effectsConfig::OutputStream stream = {.type = type.value(),
                                                          .effects = std::move(effects)};
                    postprocess.emplace_back(stream);
                } else if (aidlProcess.type.getTag() == Processing::Type::source) {
                    AudioSource aidlType =
                            aidlProcess.type.template get<Processing::Type::source>();
                    const auto type =
                            ::aidl::android::aidl2legacy_AudioSource_audio_source_t(aidlType);
                    if (!type.ok()) {
                        return;
                    }

                    std::vector<std::shared_ptr<const effectsConfig::Effect>> effects;
                    std::transform(aidlProcess.ids.begin(), aidlProcess.ids.end(),
                                   std::back_inserter(effects), getConfigEffectWithDescriptor);
                    effectsConfig::InputStream stream = {.type = type.value(),
                                                         .effects = std::move(effects)};
                    preprocess.emplace_back(stream);
                }
            };

    static std::shared_ptr<const effectsConfig::Processings> processings(
            [&]() -> std::shared_ptr<const effectsConfig::Processings> {
                std::vector<effectsConfig::InputStream> preprocess;
                std::vector<effectsConfig::OutputStream> postprocess;
                for (const auto& processing : mAidlProcessings) {
                    getConfigProcessingWithAidlProcessing(processing, preprocess, postprocess);
                }

                if (0 == preprocess.size() && 0 == postprocess.size()) {
                    return nullptr;
                }

::android::error::Result<size_t> EffectsFactoryHalAidl::getSkippedElements() const {
    if (!mEffectProcessings) {
        return ::android::base::unexpected(BAD_VALUE);
                return std::make_shared<const effectsConfig::Processings>(
                        effectsConfig::Processings({.preprocess = std::move(preprocess),
                                                    .postprocess = std::move(postprocess)}));
            }());

    return processings;
}

    // Only return 0 for AIDL, because the AIDL interface doesn't aware of configuration file
// Return 0 for AIDL, as the AIDL interface is not aware of the configuration file.
::android::error::Result<size_t> EffectsFactoryHalAidl::getSkippedElements() const {
    return 0;
}

+2 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <mutex>

#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <aidl/android/hardware/audio/effect/Processing.h>
#include <android-base/thread_annotations.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <system/thread_defs.h>
@@ -82,7 +83,7 @@ class EffectsFactoryHalAidl final : public EffectsFactoryHalInterface {
    // total number of effects including proxy effects
    const size_t mEffectCount;
    // Query result of pre and post processing from effect factory
    const std::shared_ptr<const effectsConfig::Processings> mEffectProcessings;
    const std::vector<Processing> mAidlProcessings;

    std::mutex mLock;
    uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0;  // Align with HIDL (0 is INVALID_ID)
+42 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

//#define LOG_NDEBUG 0
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -92,6 +93,47 @@ TEST(libAudioHalTest, createEffect) {
    }
}

TEST(libAudioHalTest, getProcessings) {
    auto factory = EffectsFactoryHalInterface::create();
    ASSERT_NE(nullptr, factory);

    const auto &processings = factory->getProcessings();
    if (processings) {
        EXPECT_NE(0UL, processings->preprocess.size() + processings->postprocess.size() +
                               processings->deviceprocess.size());

        auto processingChecker = [](const auto& processings) {
            if (processings.size() != 0) {
                // any process need at least 1 effect inside
                std::for_each(processings.begin(), processings.end(), [](const auto& process) {
                    EXPECT_NE(0ul, process.effects.size());
                    // any effect should have a valid name string, and not proxy
                    for (const auto& effect : process.effects) {
                        SCOPED_TRACE("Effect: {" +
                                     (effect == nullptr
                                              ? "NULL}"
                                              : ("{name: " + effect->name + ", isproxy: " +
                                                 (effect->isProxy ? "true" : "false") + ", sw: " +
                                                 (effect->libSw ? "non-null" : "null") + ", hw: " +
                                                 (effect->libHw ? "non-null" : "null") + "}")));
                        EXPECT_NE(nullptr, effect);
                        EXPECT_NE("", effect->name);
                        EXPECT_EQ(false, effect->isProxy);
                        EXPECT_EQ(nullptr, effect->libSw);
                        EXPECT_EQ(nullptr, effect->libHw);
                    }
                });
            }
        };

        processingChecker(processings->preprocess);
        processingChecker(processings->postprocess);
        processingChecker(processings->deviceprocess);
    } else {
        GTEST_SKIP() << "no processing found, skipping the test";
    }
}

TEST(libAudioHalTest, getHalVersion) {
    auto factory = EffectsFactoryHalInterface::create();
    ASSERT_NE(nullptr, factory);