blob: d2faa70f0b0913cc3161ba2a7a3778d955cdfd2e [file] [log] [blame]
Eric Laurentb82e6b72019-11-22 17:25:04 -08001/*
2**
3** Copyright 2019, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#ifndef INCLUDING_FROM_AUDIOFLINGER_H
19 #error This header file should only be included from AudioFlinger.h
20#endif
21
22// DeviceEffectManager is concealed within AudioFlinger, their lifetimes are the same.
23class DeviceEffectManager {
24public:
25 explicit DeviceEffectManager(AudioFlinger* audioFlinger)
26 : mCommandThread(new CommandThread(*this)), mAudioFlinger(*audioFlinger),
27 mMyCallback(new DeviceEffectManagerCallback(this)) {}
28
29 ~DeviceEffectManager() {
30 mCommandThread->exit();
31 }
32
33 sp<EffectHandle> createEffect_l(effect_descriptor_t *descriptor,
34 const AudioDeviceTypeAddr& device,
35 const sp<AudioFlinger::Client>& client,
Ytai Ben-Tsvi9cd89812020-07-01 17:12:06 -070036 const sp<media::IEffectClient>& effectClient,
Eric Laurentb82e6b72019-11-22 17:25:04 -080037 const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
38 int *enabled,
Eric Laurent2fe0acd2020-03-13 14:30:46 -070039 status_t *status,
Eric Laurentde8caf42021-08-11 17:19:25 +020040 bool probe,
41 bool notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -080042 void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
43 void releaseAudioPatch(audio_patch_handle_t handle);
44
45 size_t removeEffect(const sp<DeviceEffectProxy>& effect);
46 status_t createEffectHal(const effect_uuid_t *pEffectUuid,
47 int32_t sessionId, int32_t deviceId,
48 sp<EffectHalInterface> *effect);
49 status_t addEffectToHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
50 sp<EffectHalInterface> effect) {
51 return mAudioFlinger.addEffectToHal(deviceId, hwModuleId, effect);
52 };
53 status_t removeEffectFromHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
54 sp<EffectHalInterface> effect) {
55 return mAudioFlinger.removeEffectFromHal(deviceId, hwModuleId, effect);
56 };
57
58 AudioFlinger& audioFlinger() const { return mAudioFlinger; }
59
60 void dump(int fd);
61
62private:
63
64 // Thread to execute create and release patch commands asynchronously. This is needed because
65 // PatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service
66 // with mutex locked and effect management requires to call back into audio policy service
67 class Command;
68 class CommandThread : public Thread {
69 public:
70
71 enum {
72 CREATE_AUDIO_PATCH,
73 RELEASE_AUDIO_PATCH,
74 };
75
76 CommandThread(DeviceEffectManager& manager)
77 : Thread(false), mManager(manager) {}
78 ~CommandThread() override;
79
80 // Thread virtuals
81 void onFirstRef() override;
82 bool threadLoop() override;
83
84 void exit();
85
86 void createAudioPatchCommand(audio_patch_handle_t handle,
87 const PatchPanel::Patch& patch);
88 void releaseAudioPatchCommand(audio_patch_handle_t handle);
89
90 private:
91 class CommandData;
92
93 // descriptor for requested tone playback event
94 class Command: public RefBase {
95 public:
96 Command() = default;
97 Command(int command, sp<CommandData> data)
98 : mCommand(command), mData(data) {}
99
100 int mCommand = -1;
101 sp<CommandData> mData;
102 };
103
104 class CommandData: public RefBase {
105 public:
106 virtual ~CommandData() = default;
107 };
108
109 class CreateAudioPatchData : public CommandData {
110 public:
111 CreateAudioPatchData(audio_patch_handle_t handle, const PatchPanel::Patch& patch)
112 : mHandle(handle), mPatch(patch) {}
113
114 audio_patch_handle_t mHandle;
115 const PatchPanel::Patch mPatch;
116 };
117
118 class ReleaseAudioPatchData : public CommandData {
119 public:
120 ReleaseAudioPatchData(audio_patch_handle_t handle)
121 : mHandle(handle) {}
122
123 audio_patch_handle_t mHandle;
124 };
125
126 void sendCommand(sp<Command> command);
127
128 Mutex mLock;
129 Condition mWaitWorkCV;
130 std::deque <sp<Command>> mCommands; // list of pending commands
131 DeviceEffectManager& mManager;
132 };
133
134 void onCreateAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
135 void onReleaseAudioPatch(audio_patch_handle_t handle);
136
137 status_t checkEffectCompatibility(const effect_descriptor_t *desc);
138
139 Mutex mLock;
140 sp<CommandThread> mCommandThread;
141 AudioFlinger &mAudioFlinger;
142 const sp<DeviceEffectManagerCallback> mMyCallback;
143 std::map<AudioDeviceTypeAddr, sp<DeviceEffectProxy>> mDeviceEffects;
144};
145
146class DeviceEffectManagerCallback : public EffectCallbackInterface {
147public:
148 DeviceEffectManagerCallback(DeviceEffectManager *manager)
149 : mManager(*manager) {}
150
151 status_t createEffectHal(const effect_uuid_t *pEffectUuid,
152 int32_t sessionId, int32_t deviceId,
153 sp<EffectHalInterface> *effect) override {
154 return mManager.createEffectHal(pEffectUuid, sessionId, deviceId, effect);
155 }
156 status_t allocateHalBuffer(size_t size __unused,
157 sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; }
158 bool updateOrphanEffectChains(const sp<EffectBase>& effect __unused) override { return false; }
159
160 audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; }
161 bool isOutput() const override { return false; }
162 bool isOffload() const override { return false; }
163 bool isOffloadOrDirect() const override { return false; }
164 bool isOffloadOrMmap() const override { return false; }
Eric Laurent0dccd2e2021-10-26 17:40:18 +0200165 bool isSpatializer() const override { return false; }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800166
167 uint32_t sampleRate() const override { return 0; }
Eric Laurentf1f22e72021-07-13 14:04:14 +0200168 audio_channel_mask_t inChannelMask(int id __unused) const override {
169 return AUDIO_CHANNEL_NONE;
170 }
171 uint32_t inChannelCount(int id __unused) const override { return 0; }
172 audio_channel_mask_t outChannelMask() const override { return AUDIO_CHANNEL_NONE; }
173 uint32_t outChannelCount() const override { return 0; }
174
jiabineb3bda02020-06-30 14:07:03 -0700175 audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800176 size_t frameCount() const override { return 0; }
177 uint32_t latency() const override { return 0; }
178
179 status_t addEffectToHal(sp<EffectHalInterface> effect __unused) override {
180 return NO_ERROR;
181 }
182 status_t removeEffectFromHal(sp<EffectHalInterface> effect __unused) override {
183 return NO_ERROR;
184 }
185
186 bool disconnectEffectHandle(EffectHandle *handle, bool unpinIfLast) override;
187 void setVolumeForOutput(float left __unused, float right __unused) const override {}
188
189 // check if effects should be suspended or restored when a given effect is enable or disabled
190 void checkSuspendOnEffectEnabled(const sp<EffectBase>& effect __unused,
191 bool enabled __unused, bool threadLocked __unused) override {}
192 void resetVolume() override {}
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800193 product_strategy_t strategy() const override { return static_cast<product_strategy_t>(0); }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800194 int32_t activeTrackCnt() const override { return 0; }
195 void onEffectEnable(const sp<EffectBase>& effect __unused) override {}
196 void onEffectDisable(const sp<EffectBase>& effect __unused) override {}
197
198 wp<EffectChain> chain() const override { return nullptr; }
199
Eric Laurentd66d7a12021-07-13 13:35:32 +0200200 bool isAudioPolicyReady() const override {
201 return mManager.audioFlinger().isAudioPolicyReady();
202 }
203
Eric Laurentb82e6b72019-11-22 17:25:04 -0800204 int newEffectId() { return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); }
205
206 status_t addEffectToHal(audio_port_handle_t deviceId,
207 audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
208 return mManager.addEffectToHal(deviceId, hwModuleId, effect);
209 }
210 status_t removeEffectFromHal(audio_port_handle_t deviceId,
211 audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
212 return mManager.removeEffectFromHal(deviceId, hwModuleId, effect);
213 }
214private:
215 DeviceEffectManager& mManager;
216};