blob: d187df2d561e0970dca439dafaece77837afff3b [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,
40 bool probe);
Eric Laurentb82e6b72019-11-22 17:25:04 -080041 void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
42 void releaseAudioPatch(audio_patch_handle_t handle);
43
44 size_t removeEffect(const sp<DeviceEffectProxy>& effect);
45 status_t createEffectHal(const effect_uuid_t *pEffectUuid,
46 int32_t sessionId, int32_t deviceId,
47 sp<EffectHalInterface> *effect);
48 status_t addEffectToHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
49 sp<EffectHalInterface> effect) {
50 return mAudioFlinger.addEffectToHal(deviceId, hwModuleId, effect);
51 };
52 status_t removeEffectFromHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
53 sp<EffectHalInterface> effect) {
54 return mAudioFlinger.removeEffectFromHal(deviceId, hwModuleId, effect);
55 };
56
57 AudioFlinger& audioFlinger() const { return mAudioFlinger; }
58
59 void dump(int fd);
60
61private:
62
63 // Thread to execute create and release patch commands asynchronously. This is needed because
64 // PatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service
65 // with mutex locked and effect management requires to call back into audio policy service
66 class Command;
67 class CommandThread : public Thread {
68 public:
69
70 enum {
71 CREATE_AUDIO_PATCH,
72 RELEASE_AUDIO_PATCH,
73 };
74
75 CommandThread(DeviceEffectManager& manager)
76 : Thread(false), mManager(manager) {}
77 ~CommandThread() override;
78
79 // Thread virtuals
80 void onFirstRef() override;
81 bool threadLoop() override;
82
83 void exit();
84
85 void createAudioPatchCommand(audio_patch_handle_t handle,
86 const PatchPanel::Patch& patch);
87 void releaseAudioPatchCommand(audio_patch_handle_t handle);
88
89 private:
90 class CommandData;
91
92 // descriptor for requested tone playback event
93 class Command: public RefBase {
94 public:
95 Command() = default;
96 Command(int command, sp<CommandData> data)
97 : mCommand(command), mData(data) {}
98
99 int mCommand = -1;
100 sp<CommandData> mData;
101 };
102
103 class CommandData: public RefBase {
104 public:
105 virtual ~CommandData() = default;
106 };
107
108 class CreateAudioPatchData : public CommandData {
109 public:
110 CreateAudioPatchData(audio_patch_handle_t handle, const PatchPanel::Patch& patch)
111 : mHandle(handle), mPatch(patch) {}
112
113 audio_patch_handle_t mHandle;
114 const PatchPanel::Patch mPatch;
115 };
116
117 class ReleaseAudioPatchData : public CommandData {
118 public:
119 ReleaseAudioPatchData(audio_patch_handle_t handle)
120 : mHandle(handle) {}
121
122 audio_patch_handle_t mHandle;
123 };
124
125 void sendCommand(sp<Command> command);
126
127 Mutex mLock;
128 Condition mWaitWorkCV;
129 std::deque <sp<Command>> mCommands; // list of pending commands
130 DeviceEffectManager& mManager;
131 };
132
133 void onCreateAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
134 void onReleaseAudioPatch(audio_patch_handle_t handle);
135
136 status_t checkEffectCompatibility(const effect_descriptor_t *desc);
137
138 Mutex mLock;
139 sp<CommandThread> mCommandThread;
140 AudioFlinger &mAudioFlinger;
141 const sp<DeviceEffectManagerCallback> mMyCallback;
142 std::map<AudioDeviceTypeAddr, sp<DeviceEffectProxy>> mDeviceEffects;
143};
144
145class DeviceEffectManagerCallback : public EffectCallbackInterface {
146public:
147 DeviceEffectManagerCallback(DeviceEffectManager *manager)
148 : mManager(*manager) {}
149
150 status_t createEffectHal(const effect_uuid_t *pEffectUuid,
151 int32_t sessionId, int32_t deviceId,
152 sp<EffectHalInterface> *effect) override {
153 return mManager.createEffectHal(pEffectUuid, sessionId, deviceId, effect);
154 }
155 status_t allocateHalBuffer(size_t size __unused,
156 sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; }
157 bool updateOrphanEffectChains(const sp<EffectBase>& effect __unused) override { return false; }
158
159 audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; }
160 bool isOutput() const override { return false; }
161 bool isOffload() const override { return false; }
162 bool isOffloadOrDirect() const override { return false; }
163 bool isOffloadOrMmap() const override { return false; }
164
165 uint32_t sampleRate() const override { return 0; }
166 audio_channel_mask_t channelMask() const override { return AUDIO_CHANNEL_NONE; }
167 uint32_t channelCount() const override { return 0; }
jiabineb3bda02020-06-30 14:07:03 -0700168 audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800169 size_t frameCount() const override { return 0; }
170 uint32_t latency() const override { return 0; }
171
172 status_t addEffectToHal(sp<EffectHalInterface> effect __unused) override {
173 return NO_ERROR;
174 }
175 status_t removeEffectFromHal(sp<EffectHalInterface> effect __unused) override {
176 return NO_ERROR;
177 }
178
179 bool disconnectEffectHandle(EffectHandle *handle, bool unpinIfLast) override;
180 void setVolumeForOutput(float left __unused, float right __unused) const override {}
181
182 // check if effects should be suspended or restored when a given effect is enable or disabled
183 void checkSuspendOnEffectEnabled(const sp<EffectBase>& effect __unused,
184 bool enabled __unused, bool threadLocked __unused) override {}
185 void resetVolume() override {}
186 uint32_t strategy() const override { return 0; }
187 int32_t activeTrackCnt() const override { return 0; }
188 void onEffectEnable(const sp<EffectBase>& effect __unused) override {}
189 void onEffectDisable(const sp<EffectBase>& effect __unused) override {}
190
191 wp<EffectChain> chain() const override { return nullptr; }
192
193 int newEffectId() { return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); }
194
195 status_t addEffectToHal(audio_port_handle_t deviceId,
196 audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
197 return mManager.addEffectToHal(deviceId, hwModuleId, effect);
198 }
199 status_t removeEffectFromHal(audio_port_handle_t deviceId,
200 audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
201 return mManager.removeEffectFromHal(deviceId, hwModuleId, effect);
202 }
203private:
204 DeviceEffectManager& mManager;
205};