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