1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "PlaybackCapturerManager"
17 #endif
18
19 #include "playback_capturer_manager.h"
20
21 #include <cstdlib>
22 #include <cstdio>
23 #include <cstring>
24 #include <cstdint>
25 #include <vector>
26 #include <unordered_set>
27
28 #include "audio_common_log.h"
29 #include "audio_errors.h"
30 #include "playback_capturer_adapter.h"
31
32 using namespace OHOS::AudioStandard;
33
IsStreamSupportInnerCapturer(int32_t streamUsage)34 bool IsStreamSupportInnerCapturer(int32_t streamUsage)
35 {
36 PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
37 CHECK_AND_RETURN_RET_LOG(playbackCapturerMgr != nullptr, false,
38 "IsStreamSupportInnerCapturer return false for null manager.");
39
40 return playbackCapturerMgr->IsStreamSupportInnerCapturer(streamUsage);
41 }
42
IsPrivacySupportInnerCapturer(int32_t privacyType)43 bool IsPrivacySupportInnerCapturer(int32_t privacyType)
44 {
45 PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
46 CHECK_AND_RETURN_RET_LOG(playbackCapturerMgr != nullptr, false,
47 "IsPrivacySupportInnerCapturer return false for null manager.");
48
49 return playbackCapturerMgr->IsPrivacySupportInnerCapturer(privacyType);
50 }
51
IsCaptureSilently()52 bool IsCaptureSilently()
53 {
54 PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
55 CHECK_AND_RETURN_RET_LOG(playbackCapturerMgr != nullptr, false,
56 "IsCaptureSilently return false for null manager.");
57
58 return playbackCapturerMgr->IsCaptureSilently();
59 }
60
GetInnerCapturerState()61 extern "C" __attribute__((visibility("default"))) bool GetInnerCapturerState()
62 {
63 PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
64 CHECK_AND_RETURN_RET_LOG(playbackCapturerMgr != nullptr, false,
65 "IsCaptureSilently return false for null manager.");
66
67 return playbackCapturerMgr->GetInnerCapturerState();
68 }
69
SetInnerCapturerState(bool state)70 extern "C" __attribute__((visibility("default"))) void SetInnerCapturerState(bool state)
71 {
72 PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
73 CHECK_AND_RETURN_LOG(playbackCapturerMgr != nullptr, "IsCaptureSilently return false for null manager.");
74
75 playbackCapturerMgr->SetInnerCapturerState(state);
76 }
77
78 namespace OHOS {
79 namespace AudioStandard {
80
PlaybackCapturerManager()81 PlaybackCapturerManager::PlaybackCapturerManager() {}
82
~PlaybackCapturerManager()83 PlaybackCapturerManager::~PlaybackCapturerManager() {}
84
GetInstance()85 PlaybackCapturerManager* PlaybackCapturerManager::GetInstance()
86 {
87 static PlaybackCapturerManager playbackCapturerMgr;
88 return &playbackCapturerMgr;
89 }
90
SetSupportStreamUsage(std::vector<int32_t> usage)91 void PlaybackCapturerManager::SetSupportStreamUsage(std::vector<int32_t> usage)
92 {
93 std::lock_guard<std::mutex> lock(setMutex_);
94 supportStreamUsageSet_.clear();
95 if (usage.empty()) {
96 AUDIO_INFO_LOG("Clear support streamUsage");
97 return;
98 }
99 for (size_t i = 0; i < usage.size(); i++) {
100 supportStreamUsageSet_.emplace(usage[i]);
101 }
102 }
103
IsStreamSupportInnerCapturer(int32_t streamUsage)104 bool PlaybackCapturerManager::IsStreamSupportInnerCapturer(int32_t streamUsage)
105 {
106 std::lock_guard<std::mutex> lock(setMutex_);
107 if (supportStreamUsageSet_.empty()) {
108 return streamUsage == STREAM_USAGE_MEDIA || streamUsage == STREAM_USAGE_MUSIC ||
109 streamUsage == STREAM_USAGE_MOVIE || streamUsage == STREAM_USAGE_GAME ||
110 streamUsage == STREAM_USAGE_AUDIOBOOK;
111 }
112 return supportStreamUsageSet_.find(streamUsage) != supportStreamUsageSet_.end();
113 }
114
IsPrivacySupportInnerCapturer(int32_t privacyType)115 bool PlaybackCapturerManager::IsPrivacySupportInnerCapturer(int32_t privacyType)
116 {
117 return privacyType == PRIVACY_TYPE_PUBLIC;
118 }
119
SetCaptureSilentState(bool state)120 void PlaybackCapturerManager::SetCaptureSilentState(bool state)
121 {
122 isCaptureSilently_ = state;
123 }
124
IsCaptureSilently()125 bool PlaybackCapturerManager::IsCaptureSilently()
126 {
127 return isCaptureSilently_;
128 }
129
SetInnerCapturerState(bool state)130 void PlaybackCapturerManager::SetInnerCapturerState(bool state)
131 {
132 isInnerCapturerRunning_ = state;
133 }
134
GetInnerCapturerState()135 bool PlaybackCapturerManager::GetInnerCapturerState()
136 {
137 return isInnerCapturerRunning_;
138 }
139
GetDefaultUsages()140 std::vector<StreamUsage> PlaybackCapturerManager::GetDefaultUsages()
141 {
142 return defaultUsages_;
143 }
144
RegisterCapturerFilterListener(ICapturerFilterListener * listener)145 bool PlaybackCapturerManager::RegisterCapturerFilterListener(ICapturerFilterListener *listener)
146 {
147 if (listener == nullptr || listener_ != nullptr) {
148 AUDIO_ERR_LOG("Register fail: listener is %{public}s", (listener == nullptr ? "null." : "already set."));
149 return false;
150 }
151 AUDIO_INFO_LOG("Register success");
152 listener_ = listener;
153 return true;
154 }
155
SetPlaybackCapturerFilterInfo(uint32_t sessionId,const AudioPlaybackCaptureConfig & config,int32_t innerCapId)156 int32_t PlaybackCapturerManager::SetPlaybackCapturerFilterInfo(uint32_t sessionId,
157 const AudioPlaybackCaptureConfig &config, int32_t innerCapId)
158 {
159 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, ERR_ILLEGAL_STATE, "listener is null!");
160
161 return listener_->OnCapturerFilterChange(sessionId, config, innerCapId);
162 }
163
RemovePlaybackCapturerFilterInfo(uint32_t sessionId,int32_t innerCapId)164 int32_t PlaybackCapturerManager::RemovePlaybackCapturerFilterInfo(uint32_t sessionId, int32_t innerCapId)
165 {
166 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, ERR_ILLEGAL_STATE, "listener is null!");
167 return listener_->OnCapturerFilterRemove(sessionId, innerCapId);
168 }
169
CheckCaptureLimit(const AudioPlaybackCaptureConfig & config,int32_t & innerCapId)170 int32_t PlaybackCapturerManager::CheckCaptureLimit(const AudioPlaybackCaptureConfig &config, int32_t &innerCapId)
171 {
172 bool isSame = false;
173 AudioPlaybackCaptureConfig newConfig = config;
174 if (newConfig.filterOptions.usages.size() == 0) {
175 std::vector<StreamUsage> defalutUsages = GetDefaultUsages();
176 for (size_t i = 0; i < defalutUsages.size(); i++) {
177 newConfig.filterOptions.usages.push_back(defalutUsages[i]);
178 }
179 }
180 std::lock_guard<std::mutex> lock(filterMapMutex_);
181 for (auto &filter : filters_) {
182 if (filter.second.filterConfig == newConfig) {
183 AUDIO_INFO_LOG("Capture num reuse innerId:%{public}d", filter.first);
184 innerCapId = filter.first;
185 filter.second.ref += 1;
186 isSame = true;
187 break;
188 }
189 }
190 if (!isSame && filters_.size() >= innerCapLimit_) {
191 AUDIO_ERR_LOG("Capture nume over limit");
192 innerCapId = 0;
193 return ERR_ADD_CAPTURE_OVER_LIMIT;
194 }
195 if (!isSame) {
196 GetFilterIndex();
197 innerCapId = filterNowIndex_;
198 AUDIO_INFO_LOG("Capture num add innerId:%{public}d", innerCapId);
199 CaptureFilterRef captureFilter;
200 captureFilter.ref = 1;
201 captureFilter.filterConfig = newConfig;
202 filters_[filterNowIndex_] = captureFilter;
203 }
204 return SUCCESS;
205 }
206
GetFilterIndex()207 uint32_t PlaybackCapturerManager::GetFilterIndex()
208 {
209 if (filterNowIndex_ >= innerCapLimit_) {
210 filterNowIndex_ = 0;
211 }
212 return (++filterNowIndex_);
213 }
214
SetInnerCapLimit(uint32_t innerCapLimit)215 int32_t PlaybackCapturerManager::SetInnerCapLimit(uint32_t innerCapLimit)
216 {
217 innerCapLimit_ = innerCapLimit;
218 return SUCCESS;
219 }
220
CheckReleaseUnloadModernInnerCapSink(int32_t innerCapId)221 bool PlaybackCapturerManager::CheckReleaseUnloadModernInnerCapSink(int32_t innerCapId)
222 {
223 bool result = false;
224 std::lock_guard<std::mutex> lock(filterMapMutex_);
225 if (filters_.count(innerCapId)) {
226 if (filters_[innerCapId].ref <= 1) {
227 filters_.erase(innerCapId);
228 result = true;
229 } else {
230 filters_[innerCapId].ref -= 1;
231 }
232 }
233 return result;
234 }
235 } // namespace OHOS
236 } // namespace AudioStandard