blob: b7853f0d63c2fcf8bfadd883161a8c19c8945810 [file] [log] [blame]
Vlad Popa5161f8a2022-10-10 16:17:20 +02001/*
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
22class 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
27class PatchCommandThread : public Thread {
28public:
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
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
60private:
61 class CommandData;
62
63 // Command type received from the PatchPanel
64 class Command: public RefBase {
65 public:
66 Command() = default;
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:
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:
87 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};