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