blob: ffb8a194d7dded7b111cd3533d439ef35fd8ae6b [file] [log] [blame]
Shunkai Yao5c718342023-02-23 23:49:51 +00001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <map>
20#include <memory>
21
22#include <aidl/android/hardware/audio/effect/BnEffect.h>
23#include <aidl/android/hardware/audio/effect/BnFactory.h>
24#include <fmq/AidlMessageQueue.h>
25#include <system/audio_effect.h>
26
27namespace android {
28namespace effect {
29
30/**
31 * EffectProxy is the proxy for one or more effect AIDL implementations (sub effect) of same type.
32 * The audio framework use EffectProxy as a composite implementation of all sub effect
33 * implementations.
34 *
35 * At any given time, there is only one active effect which consuming and producing data for each
36 * proxy. All setter commands (except the legacy EFFECT_CMD_OFFLOAD, it will be handled by the audio
37 * framework directly) and parameters will be pass through to all sub effects, the getter commands
38 * and parameters will only passthrough to the active sub-effect.
39 *
40 */
Shunkai Yao24ee5992023-03-27 17:32:04 +000041class EffectProxy final : public ::aidl::android::hardware::audio::effect::BnEffect {
Shunkai Yao5c718342023-02-23 23:49:51 +000042 public:
43 EffectProxy(const ::aidl::android::hardware::audio::effect::Descriptor::Identity& id,
44 const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory);
45
46 /**
47 * Add a sub effect into the proxy, the descriptor of candidate sub-effect need to have same
48 * proxy UUID as mUuid.
49 */
50 ndk::ScopedAStatus addSubEffect(
51 const ::aidl::android::hardware::audio::effect::Descriptor& sub);
52
53 /**
54 * Create all sub-effects via AIDL IFactory, always call create() after all sub-effects added
55 * successfully with addSubEffect.
56 */
57 ndk::ScopedAStatus create();
58
59 /**
60 * Destroy all sub-effects via AIDL IFactory, always call create() after all sub-effects added
61 * successfully with addSubEffect.
62 */
63 ndk::ScopedAStatus destroy();
64
65 /**
66 * Handle offload parameter setting from framework.
67 */
68 ndk::ScopedAStatus setOffloadParam(const effect_offload_param_t* offload);
69
70 /**
71 * Get the const reference of the active sub-effect return parameters.
72 * Always use this interface to get the effect open return parameters (FMQs) after a success
73 * setOffloadParam() call.
74 */
75 const IEffect::OpenEffectReturn* getEffectReturnParam();
76
77 // IEffect interfaces override
78 ndk::ScopedAStatus open(
79 const ::aidl::android::hardware::audio::effect::Parameter::Common& common,
80 const std::optional<::aidl::android::hardware::audio::effect::Parameter::Specific>&
81 specific,
82 ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn* ret) override;
83 ndk::ScopedAStatus close() override;
84 ndk::ScopedAStatus getDescriptor(
85 ::aidl::android::hardware::audio::effect::Descriptor* desc) override;
86 ndk::ScopedAStatus command(::aidl::android::hardware::audio::effect::CommandId id) override;
87 ndk::ScopedAStatus getState(::aidl::android::hardware::audio::effect::State* state) override;
88 ndk::ScopedAStatus setParameter(
89 const ::aidl::android::hardware::audio::effect::Parameter& param) override;
90 ndk::ScopedAStatus getParameter(
91 const ::aidl::android::hardware::audio::effect::Parameter::Id& id,
92 ::aidl::android::hardware::audio::effect::Parameter* param) override;
93
94 private:
95 // Proxy identity, copy from one sub-effect, and update the implementation UUID to proxy UUID
96 const ::aidl::android::hardware::audio::effect::Descriptor::Identity mIdentity;
97 const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
98
99 // A map of sub effects descriptor to the IEffect handle and return FMQ
100 enum SubEffectTupleIndex { HANDLE, DESCRIPTOR, RETURN };
101 using EffectProxySub =
102 std::tuple<std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>,
103 ::aidl::android::hardware::audio::effect::Descriptor,
104 ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn>;
105 std::map<const ::aidl::android::hardware::audio::effect::Descriptor::Identity, EffectProxySub>
106 mSubEffects;
107
108 // Descriptor of the only active effect in the mSubEffects map
109 ::aidl::android::hardware::audio::effect::Descriptor::Identity mActiveSub;
110
111 // keep the flag of sub-effects
112 ::aidl::android::hardware::audio::effect::Flags mSubFlags;
113
114 ndk::ScopedAStatus runWithActiveSubEffectThenOthers(
115 std::function<ndk::ScopedAStatus(
116 const std::shared_ptr<
117 ::aidl::android::hardware::audio::effect::IEffect>&)> const& func);
118
119 ndk::ScopedAStatus runWithActiveSubEffect(
120 std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func);
121
122 ndk::ScopedAStatus runWithAllSubEffects(
123 std::function<ndk::ScopedAStatus(std::shared_ptr<IEffect>&)> const& func);
124
125 // close and release all sub-effects
126 ~EffectProxy();
127};
128
129} // namespace effect
130} // namespace android