blob: 6cf0505bfb9468c276f95a1f356188749270495e [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
Andy Hungd6e86392023-07-13 19:33:17 -070018#pragma once
19
20namespace android {
Vlad Popa5161f8a2022-10-10 16:17:20 +020021
22class Command;
23
24// Thread to execute create and release patch commands asynchronously. This is needed because
Andy Hung8e6b62a2023-07-13 18:11:33 -070025// IAfPatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service
Vlad Popa5161f8a2022-10-10 16:17:20 +020026// 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,
François Gaffie58e73af2023-02-15 11:47:24 +010033 UPDATE_AUDIO_PATCH,
Vlad Popa5161f8a2022-10-10 16:17:20 +020034 };
35
36 class PatchCommandListener : public virtual RefBase {
37 public:
38 virtual void onCreateAudioPatch(audio_patch_handle_t handle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070039 const IAfPatchPanel::Patch& patch) = 0;
Vlad Popa5161f8a2022-10-10 16:17:20 +020040 virtual void onReleaseAudioPatch(audio_patch_handle_t handle) = 0;
François Gaffie58e73af2023-02-15 11:47:24 +010041 virtual void onUpdateAudioPatch(audio_patch_handle_t oldHandle,
42 audio_patch_handle_t newHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070043 const IAfPatchPanel::Patch& patch) = 0;
Vlad Popa5161f8a2022-10-10 16:17:20 +020044 };
45
46 PatchCommandThread() : Thread(false /* canCallJava */) {}
47 ~PatchCommandThread() override;
48
49 void addListener(const sp<PatchCommandListener>& listener);
50
Andy Hung8e6b62a2023-07-13 18:11:33 -070051 void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch);
Vlad Popa5161f8a2022-10-10 16:17:20 +020052 void releaseAudioPatch(audio_patch_handle_t handle);
François Gaffie58e73af2023-02-15 11:47:24 +010053 void updateAudioPatch(audio_patch_handle_t oldHandle,
54 audio_patch_handle_t newHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070055 const IAfPatchPanel::Patch& patch);
Vlad Popa5161f8a2022-10-10 16:17:20 +020056
57 // Thread virtuals
58 void onFirstRef() override;
59 bool threadLoop() override;
60
61 void exit();
62
63 void createAudioPatchCommand(audio_patch_handle_t handle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070064 const IAfPatchPanel::Patch& patch);
Vlad Popa5161f8a2022-10-10 16:17:20 +020065 void releaseAudioPatchCommand(audio_patch_handle_t handle);
François Gaffie58e73af2023-02-15 11:47:24 +010066 void updateAudioPatchCommand(audio_patch_handle_t oldHandle,
67 audio_patch_handle_t newHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070068 const IAfPatchPanel::Patch& patch);
Vlad Popa5161f8a2022-10-10 16:17:20 +020069private:
70 class CommandData;
71
72 // Command type received from the PatchPanel
73 class Command: public RefBase {
74 public:
75 Command() = default;
76 Command(int command, const sp<CommandData>& data)
77 : mCommand(command), mData(data) {}
78
79 const int mCommand = -1;
80 const sp<CommandData> mData;
81 };
82
83 class CommandData: public RefBase {};
84
85 class CreateAudioPatchData : public CommandData {
86 public:
Andy Hung8e6b62a2023-07-13 18:11:33 -070087 CreateAudioPatchData(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch)
Vlad Popa5161f8a2022-10-10 16:17:20 +020088 : mHandle(handle), mPatch(patch) {}
89
90 const audio_patch_handle_t mHandle;
Andy Hung8e6b62a2023-07-13 18:11:33 -070091 const IAfPatchPanel::Patch mPatch;
Vlad Popa5161f8a2022-10-10 16:17:20 +020092 };
93
94 class ReleaseAudioPatchData : public CommandData {
95 public:
Andy Hungf9829e42022-10-06 12:09:49 -070096 explicit ReleaseAudioPatchData(audio_patch_handle_t handle)
Vlad Popa5161f8a2022-10-10 16:17:20 +020097 : mHandle(handle) {}
98
99 audio_patch_handle_t mHandle;
100 };
101
François Gaffie58e73af2023-02-15 11:47:24 +0100102 class UpdateAudioPatchData : public CommandData {
103 public:
104 UpdateAudioPatchData(audio_patch_handle_t oldHandle,
105 audio_patch_handle_t newHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -0700106 const IAfPatchPanel::Patch& patch)
François Gaffie58e73af2023-02-15 11:47:24 +0100107 : mOldHandle(oldHandle), mNewHandle(newHandle), mPatch(patch) {}
108
109 const audio_patch_handle_t mOldHandle;
110 const audio_patch_handle_t mNewHandle;
Andy Hung8e6b62a2023-07-13 18:11:33 -0700111 const IAfPatchPanel::Patch mPatch;
François Gaffie58e73af2023-02-15 11:47:24 +0100112 };
113
Vlad Popa5161f8a2022-10-10 16:17:20 +0200114 void sendCommand(const sp<Command>& command);
115
116 std::string mThreadName;
117 std::mutex mLock;
118 std::condition_variable mWaitWorkCV;
119 std::deque<sp<Command>> mCommands GUARDED_BY(mLock); // list of pending commands
120
121 std::mutex mListenerLock;
122 std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(mListenerLock);
123};
Andy Hungd6e86392023-07-13 19:33:17 -0700124
125} // namespace android