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