1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #pragma once 18*ec779b8eSAndroid Build Coastguard Worker 19*ec779b8eSAndroid Build Coastguard Worker #include <map> 20*ec779b8eSAndroid Build Coastguard Worker #include <memory> 21*ec779b8eSAndroid Build Coastguard Worker 22*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/effect/BnEffect.h> 23*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/effect/BnFactory.h> 24*ec779b8eSAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h> 25*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effect.h> 26*ec779b8eSAndroid Build Coastguard Worker 27*ec779b8eSAndroid Build Coastguard Worker namespace android { 28*ec779b8eSAndroid Build Coastguard Worker namespace effect { 29*ec779b8eSAndroid Build Coastguard Worker 30*ec779b8eSAndroid Build Coastguard Worker /** 31*ec779b8eSAndroid Build Coastguard Worker * EffectProxy is the proxy for one or more effect AIDL implementations (sub effect) of same type. 32*ec779b8eSAndroid Build Coastguard Worker * The audio framework use EffectProxy as a composite implementation of all sub effect 33*ec779b8eSAndroid Build Coastguard Worker * implementations. 34*ec779b8eSAndroid Build Coastguard Worker * 35*ec779b8eSAndroid Build Coastguard Worker * At any given time, there is only one active effect which consuming and producing data for each 36*ec779b8eSAndroid Build Coastguard Worker * proxy. All setter commands (except the legacy EFFECT_CMD_OFFLOAD, it will be handled by the audio 37*ec779b8eSAndroid Build Coastguard Worker * framework directly) and parameters will be pass through to all sub effects, the getter commands 38*ec779b8eSAndroid Build Coastguard Worker * and parameters will only passthrough to the active sub-effect. 39*ec779b8eSAndroid Build Coastguard Worker * 40*ec779b8eSAndroid Build Coastguard Worker */ 41*ec779b8eSAndroid Build Coastguard Worker class EffectProxy final : public ::aidl::android::hardware::audio::effect::BnEffect { 42*ec779b8eSAndroid Build Coastguard Worker public: 43*ec779b8eSAndroid Build Coastguard Worker EffectProxy( 44*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::media::audio::common::AudioUuid& uuid, 45*ec779b8eSAndroid Build Coastguard Worker const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& descriptors, 46*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory); 47*ec779b8eSAndroid Build Coastguard Worker 48*ec779b8eSAndroid Build Coastguard Worker /** 49*ec779b8eSAndroid Build Coastguard Worker * Handle offload parameter setting from framework. 50*ec779b8eSAndroid Build Coastguard Worker */ 51*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus setOffloadParam(const effect_offload_param_t* offload); 52*ec779b8eSAndroid Build Coastguard Worker 53*ec779b8eSAndroid Build Coastguard Worker /** 54*ec779b8eSAndroid Build Coastguard Worker * Destroy all sub-effects via AIDL IFactory. 55*ec779b8eSAndroid Build Coastguard Worker */ 56*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus destroy(); 57*ec779b8eSAndroid Build Coastguard Worker 58*ec779b8eSAndroid Build Coastguard Worker // IEffect interfaces override 59*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus open( 60*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Parameter::Common& common, 61*ec779b8eSAndroid Build Coastguard Worker const std::optional<::aidl::android::hardware::audio::effect::Parameter::Specific>& 62*ec779b8eSAndroid Build Coastguard Worker specific, 63*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn* ret) override; 64*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus close() override; 65*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus reopen( 66*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn* ret) override; 67*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus getDescriptor( 68*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::Descriptor* desc) override; 69*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus command(::aidl::android::hardware::audio::effect::CommandId id) override; 70*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus getState(::aidl::android::hardware::audio::effect::State* state) override; 71*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus setParameter( 72*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Parameter& param) override; 73*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus getParameter( 74*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Parameter::Id& id, 75*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::Parameter* param) override; 76*ec779b8eSAndroid Build Coastguard Worker 77*ec779b8eSAndroid Build Coastguard Worker static ndk::ScopedAStatus buildDescriptor( 78*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::media::audio::common::AudioUuid& uuid, 79*ec779b8eSAndroid Build Coastguard Worker const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& subEffectDescs, 80*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::Descriptor* desc); 81*ec779b8eSAndroid Build Coastguard Worker 82*ec779b8eSAndroid Build Coastguard Worker /** 83*ec779b8eSAndroid Build Coastguard Worker * Get the const reference of the active sub-effect return parameters. 84*ec779b8eSAndroid Build Coastguard Worker * Always use this interface to get the effect open return parameters (FMQs) after a success 85*ec779b8eSAndroid Build Coastguard Worker * setOffloadParam() call. 86*ec779b8eSAndroid Build Coastguard Worker */ 87*ec779b8eSAndroid Build Coastguard Worker using StatusMQ = ::android::AidlMessageQueue< 88*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::IEffect::Status, 89*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>; 90*ec779b8eSAndroid Build Coastguard Worker using DataMQ = ::android::AidlMessageQueue< 91*ec779b8eSAndroid Build Coastguard Worker float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>; getStatusMQ()92*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<StatusMQ>& getStatusMQ() const { 93*ec779b8eSAndroid Build Coastguard Worker return mSubEffects[mActiveSubIdx].effectMq.statusQ; 94*ec779b8eSAndroid Build Coastguard Worker } getInputMQ()95*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<DataMQ>& getInputMQ() const { 96*ec779b8eSAndroid Build Coastguard Worker return mSubEffects[mActiveSubIdx].effectMq.inputQ; 97*ec779b8eSAndroid Build Coastguard Worker } getOutputMQ()98*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<DataMQ>& getOutputMQ() const { 99*ec779b8eSAndroid Build Coastguard Worker return mSubEffects[mActiveSubIdx].effectMq.outputQ; 100*ec779b8eSAndroid Build Coastguard Worker } 101*ec779b8eSAndroid Build Coastguard Worker 102*ec779b8eSAndroid Build Coastguard Worker bool isBypassing() const; 103*ec779b8eSAndroid Build Coastguard Worker bool isTunnel() const; 104*ec779b8eSAndroid Build Coastguard Worker 105*ec779b8eSAndroid Build Coastguard Worker // call dump for all sub-effects 106*ec779b8eSAndroid Build Coastguard Worker binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; 107*ec779b8eSAndroid Build Coastguard Worker 108*ec779b8eSAndroid Build Coastguard Worker std::string toString(size_t indent = 0) const; 109*ec779b8eSAndroid Build Coastguard Worker 110*ec779b8eSAndroid Build Coastguard Worker private: 111*ec779b8eSAndroid Build Coastguard Worker // The shared capability of all sub-effects 112*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Capability mSharedCapability; 113*ec779b8eSAndroid Build Coastguard Worker // Proxy descriptor common part, copy from one sub-effect, and update the implementation UUID to 114*ec779b8eSAndroid Build Coastguard Worker // proxy UUID, proxy descriptor capability part comes from the active sub-effect capability 115*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Descriptor::Common mDescriptorCommon; 116*ec779b8eSAndroid Build Coastguard Worker 117*ec779b8eSAndroid Build Coastguard Worker struct EffectMQ { 118*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<StatusMQ> statusQ; 119*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<DataMQ> inputQ, outputQ; 120*ec779b8eSAndroid Build Coastguard Worker }; 121*ec779b8eSAndroid Build Coastguard Worker struct SubEffect { 122*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::audio::effect::Descriptor descriptor; 123*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> handle; 124*ec779b8eSAndroid Build Coastguard Worker EffectMQ effectMq; 125*ec779b8eSAndroid Build Coastguard Worker }; 126*ec779b8eSAndroid Build Coastguard Worker std::vector<SubEffect> mSubEffects; 127*ec779b8eSAndroid Build Coastguard Worker 128*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory; 129*ec779b8eSAndroid Build Coastguard Worker 130*ec779b8eSAndroid Build Coastguard Worker // index of the active sub-effects, by default use the first one (index 0) 131*ec779b8eSAndroid Build Coastguard Worker // It's safe to assume there will always at least two SubEffects in mSubEffects 132*ec779b8eSAndroid Build Coastguard Worker size_t mActiveSubIdx = 0; 133*ec779b8eSAndroid Build Coastguard Worker 134*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus runWithActiveSubEffectThenOthers( 135*ec779b8eSAndroid Build Coastguard Worker std::function<ndk::ScopedAStatus( 136*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr< 137*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::audio::effect::IEffect>&)> const& func); 138*ec779b8eSAndroid Build Coastguard Worker 139*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus runWithActiveSubEffect( 140*ec779b8eSAndroid Build Coastguard Worker std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func); 141*ec779b8eSAndroid Build Coastguard Worker 142*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus runWithAllSubEffects( 143*ec779b8eSAndroid Build Coastguard Worker std::function<ndk::ScopedAStatus(std::shared_ptr<IEffect>&)> const& func); 144*ec779b8eSAndroid Build Coastguard Worker 145*ec779b8eSAndroid Build Coastguard Worker // build Descriptor.Common with all sub-effect descriptors 146*ec779b8eSAndroid Build Coastguard Worker static ::aidl::android::hardware::audio::effect::Descriptor::Common buildDescriptorCommon( 147*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::media::audio::common::AudioUuid& uuid, 148*ec779b8eSAndroid Build Coastguard Worker const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& 149*ec779b8eSAndroid Build Coastguard Worker subEffectDescs); 150*ec779b8eSAndroid Build Coastguard Worker 151*ec779b8eSAndroid Build Coastguard Worker // build a shared capability with all sub-effect descriptors 152*ec779b8eSAndroid Build Coastguard Worker static ::aidl::android::hardware::audio::effect::Capability buildDescriptorCapability( 153*ec779b8eSAndroid Build Coastguard Worker const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& 154*ec779b8eSAndroid Build Coastguard Worker subEffectDescs); 155*ec779b8eSAndroid Build Coastguard Worker 156*ec779b8eSAndroid Build Coastguard Worker // close and release all sub-effects 157*ec779b8eSAndroid Build Coastguard Worker ~EffectProxy(); 158*ec779b8eSAndroid Build Coastguard Worker }; 159*ec779b8eSAndroid Build Coastguard Worker 160*ec779b8eSAndroid Build Coastguard Worker } // namespace effect 161*ec779b8eSAndroid Build Coastguard Worker } // namespace android 162