/* ** ** Copyright 2022, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #ifndef INCLUDING_FROM_AUDIOFLINGER_H #error This header file should only be included from AudioFlinger.h #endif class Command; // Thread to execute create and release patch commands asynchronously. This is needed because // PatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service // with mutex locked and effect management requires to call back into audio policy service class PatchCommandThread : public Thread { public: enum { CREATE_AUDIO_PATCH, RELEASE_AUDIO_PATCH, }; class PatchCommandListener : public virtual RefBase { public: virtual void onCreateAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch) = 0; virtual void onReleaseAudioPatch(audio_patch_handle_t handle) = 0; }; PatchCommandThread() : Thread(false /* canCallJava */) {} ~PatchCommandThread() override; void addListener(const sp& listener); void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch); void releaseAudioPatch(audio_patch_handle_t handle); // Thread virtuals void onFirstRef() override; bool threadLoop() override; void exit(); void createAudioPatchCommand(audio_patch_handle_t handle, const PatchPanel::Patch& patch); void releaseAudioPatchCommand(audio_patch_handle_t handle); private: class CommandData; // Command type received from the PatchPanel class Command: public RefBase { public: Command() = default; Command(int command, const sp& data) : mCommand(command), mData(data) {} const int mCommand = -1; const sp mData; }; class CommandData: public RefBase {}; class CreateAudioPatchData : public CommandData { public: CreateAudioPatchData(audio_patch_handle_t handle, const PatchPanel::Patch& patch) : mHandle(handle), mPatch(patch) {} const audio_patch_handle_t mHandle; const PatchPanel::Patch mPatch; }; class ReleaseAudioPatchData : public CommandData { public: explicit ReleaseAudioPatchData(audio_patch_handle_t handle) : mHandle(handle) {} audio_patch_handle_t mHandle; }; void sendCommand(const sp& command); std::string mThreadName; std::mutex mLock; std::condition_variable mWaitWorkCV; std::deque> mCommands GUARDED_BY(mLock); // list of pending commands std::mutex mListenerLock; std::vector> mListeners GUARDED_BY(mListenerLock); };