1 /*
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.
23 class DeviceEffectManager {
24 public:
DeviceEffectManager(AudioFlinger * audioFlinger)25     explicit DeviceEffectManager(AudioFlinger* audioFlinger)
26         : mCommandThread(new CommandThread(*this)), mAudioFlinger(*audioFlinger),
27         mMyCallback(new DeviceEffectManagerCallback(this)) {}
28 
~DeviceEffectManager()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<media::IEffectClient>& effectClient,
37                 const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
38                 int *enabled,
39                 status_t *status,
40                 bool probe,
41                 bool notifyFramesProcessed);
42     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);
addEffectToHal(audio_port_handle_t deviceId,audio_module_handle_t hwModuleId,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     };
removeEffectFromHal(audio_port_handle_t deviceId,audio_module_handle_t hwModuleId,sp<EffectHalInterface> effect)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 
audioFlinger()58     AudioFlinger& audioFlinger() const { return mAudioFlinger; }
59 
60     void dump(int fd);
61 
62 private:
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 
CommandThread(DeviceEffectManager & manager)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;
Command(int command,sp<CommandData> data)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:
CreateAudioPatchData(audio_patch_handle_t handle,const PatchPanel::Patch & patch)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:
ReleaseAudioPatchData(audio_patch_handle_t handle)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 
146 class DeviceEffectManagerCallback :  public EffectCallbackInterface {
147 public:
DeviceEffectManagerCallback(DeviceEffectManager * manager)148             DeviceEffectManagerCallback(DeviceEffectManager *manager)
149                 : mManager(*manager) {}
150 
createEffectHal(const effect_uuid_t * pEffectUuid,int32_t sessionId,int32_t deviceId,sp<EffectHalInterface> * effect)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             }
allocateHalBuffer(size_t size __unused,sp<EffectBufferHalInterface> * buffer __unused)156     status_t allocateHalBuffer(size_t size __unused,
157             sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; }
updateOrphanEffectChains(const sp<EffectBase> & effect __unused)158     bool updateOrphanEffectChains(const sp<EffectBase>& effect __unused) override { return false; }
159 
io()160     audio_io_handle_t io() const override  { return AUDIO_IO_HANDLE_NONE; }
isOutput()161     bool isOutput() const override { return false; }
isOffload()162     bool isOffload() const override { return false; }
isOffloadOrDirect()163     bool isOffloadOrDirect() const override { return false; }
isOffloadOrMmap()164     bool isOffloadOrMmap() const override { return false; }
isSpatializer()165     bool isSpatializer() const override { return false; }
166 
sampleRate()167     uint32_t  sampleRate() const override { return 0; }
inChannelMask(int id __unused)168     audio_channel_mask_t inChannelMask(int id __unused) const override {
169         return AUDIO_CHANNEL_NONE;
170     }
inChannelCount(int id __unused)171     uint32_t inChannelCount(int id __unused) const override { return 0; }
outChannelMask()172     audio_channel_mask_t outChannelMask() const override { return AUDIO_CHANNEL_NONE; }
outChannelCount()173     uint32_t outChannelCount() const override { return 0; }
174 
hapticChannelMask()175     audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
frameCount()176     size_t    frameCount() const override  { return 0; }
latency()177     uint32_t  latency() const override  { return 0; }
178 
addEffectToHal(sp<EffectHalInterface> effect __unused)179     status_t addEffectToHal(sp<EffectHalInterface> effect __unused) override {
180         return NO_ERROR;
181     }
removeEffectFromHal(sp<EffectHalInterface> effect __unused)182     status_t removeEffectFromHal(sp<EffectHalInterface> effect __unused) override {
183         return NO_ERROR;
184     }
185 
186     bool disconnectEffectHandle(EffectHandle *handle, bool unpinIfLast) override;
setVolumeForOutput(float left __unused,float right __unused)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
checkSuspendOnEffectEnabled(const sp<EffectBase> & effect __unused,bool enabled __unused,bool threadLocked __unused)190     void checkSuspendOnEffectEnabled(const sp<EffectBase>& effect __unused,
191                           bool enabled __unused, bool threadLocked __unused) override {}
resetVolume()192     void resetVolume() override {}
strategy()193     product_strategy_t strategy() const override  { return static_cast<product_strategy_t>(0); }
activeTrackCnt()194     int32_t activeTrackCnt() const override { return 0; }
onEffectEnable(const sp<EffectBase> & effect __unused)195     void onEffectEnable(const sp<EffectBase>& effect __unused) override {}
onEffectDisable(const sp<EffectBase> & effect __unused)196     void onEffectDisable(const sp<EffectBase>& effect __unused) override {}
197 
chain()198     wp<EffectChain> chain() const override { return nullptr; }
199 
isAudioPolicyReady()200     bool isAudioPolicyReady() const override {
201         return mManager.audioFlinger().isAudioPolicyReady();
202     }
203 
newEffectId()204     int newEffectId() { return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); }
205 
addEffectToHal(audio_port_handle_t deviceId,audio_module_handle_t hwModuleId,sp<EffectHalInterface> effect)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     }
removeEffectFromHal(audio_port_handle_t deviceId,audio_module_handle_t hwModuleId,sp<EffectHalInterface> effect)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     }
214 private:
215     DeviceEffectManager& mManager;
216 };
217