1 /* 2 ** 3 ** Copyright 2022, 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 class Command; 23 24 // Thread to execute create and release patch commands asynchronously. This is needed because 25 // PatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service 26 // with mutex locked and effect management requires to call back into audio policy service 27 class PatchCommandThread : public Thread { 28 public: 29 30 enum { 31 CREATE_AUDIO_PATCH, 32 RELEASE_AUDIO_PATCH, 33 }; 34 35 class PatchCommandListener : public virtual RefBase { 36 public: 37 virtual void onCreateAudioPatch(audio_patch_handle_t handle, 38 const PatchPanel::Patch& patch) = 0; 39 virtual void onReleaseAudioPatch(audio_patch_handle_t handle) = 0; 40 }; 41 PatchCommandThread()42 PatchCommandThread() : Thread(false /* canCallJava */) {} 43 ~PatchCommandThread() override; 44 45 void addListener(const sp<PatchCommandListener>& listener); 46 47 void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch); 48 void releaseAudioPatch(audio_patch_handle_t handle); 49 50 // Thread virtuals 51 void onFirstRef() override; 52 bool threadLoop() override; 53 54 void exit(); 55 56 void createAudioPatchCommand(audio_patch_handle_t handle, 57 const PatchPanel::Patch& patch); 58 void releaseAudioPatchCommand(audio_patch_handle_t handle); 59 60 private: 61 class CommandData; 62 63 // Command type received from the PatchPanel 64 class Command: public RefBase { 65 public: 66 Command() = default; Command(int command,const sp<CommandData> & data)67 Command(int command, const sp<CommandData>& data) 68 : mCommand(command), mData(data) {} 69 70 const int mCommand = -1; 71 const sp<CommandData> mData; 72 }; 73 74 class CommandData: public RefBase {}; 75 76 class CreateAudioPatchData : public CommandData { 77 public: CreateAudioPatchData(audio_patch_handle_t handle,const PatchPanel::Patch & patch)78 CreateAudioPatchData(audio_patch_handle_t handle, const PatchPanel::Patch& patch) 79 : mHandle(handle), mPatch(patch) {} 80 81 const audio_patch_handle_t mHandle; 82 const PatchPanel::Patch mPatch; 83 }; 84 85 class ReleaseAudioPatchData : public CommandData { 86 public: ReleaseAudioPatchData(audio_patch_handle_t handle)87 explicit ReleaseAudioPatchData(audio_patch_handle_t handle) 88 : mHandle(handle) {} 89 90 audio_patch_handle_t mHandle; 91 }; 92 93 void sendCommand(const sp<Command>& command); 94 95 std::string mThreadName; 96 std::mutex mLock; 97 std::condition_variable mWaitWorkCV; 98 std::deque<sp<Command>> mCommands GUARDED_BY(mLock); // list of pending commands 99 100 std::mutex mListenerLock; 101 std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(mListenerLock); 102 }; 103