• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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