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