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

Commit 00f31a81 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: 4db7a2e7

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



Change-Id: I00dcc89200238df1e0abef122b6fd2d2fac8b5d3
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents ecb507d8 4db7a2e7
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);