1 /*
2 * Copyright (c) 2023 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 "HpaeAdapterManager"
17 #endif
18
19 #include "hpae_adapter_manager.h"
20 #include <sstream>
21 #include <atomic>
22 #include "audio_errors.h"
23 #include "hpae_renderer_stream_impl.h"
24 #include "hpae_capturer_stream_impl.h"
25 #include "audio_utils.h"
26 #include "audio_info.h"
27 #include "core_service_handler.h"
28 #include "policy_handler.h"
29 #include "audio_engine_log.h"
30 namespace OHOS {
31 namespace AudioStandard {
32
33 const char* PRO_INNER_CAPTURER_SOURCE = "Speaker";
34 const char* PRO_DUAL_PLAYBACK_SINK = "Speaker";
35
HpaeAdapterManager(ManagerType type)36 HpaeAdapterManager::HpaeAdapterManager(ManagerType type)
37 {
38 AUDIO_INFO_LOG("Constructor with type:%{public}d", type);
39 managerType_ = type;
40 }
41
CreateRender(AudioProcessConfig processConfig,std::shared_ptr<IRendererStream> & stream)42 int32_t HpaeAdapterManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr<IRendererStream> &stream)
43 {
44 AUDIO_DEBUG_LOG("Create renderer start");
45 uint32_t sessionId = 0;
46 sessionId = processConfig.originalSessionId;
47 if (managerType_ == DUP_PLAYBACK || managerType_ == DUAL_PLAYBACK ||
48 processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) {
49 sessionId = CoreServiceHandler::GetInstance().GenerateSessionId();
50 }
51 processConfig.originalSessionId = sessionId;
52 AUDIO_INFO_LOG("Create [%{public}d] type renderer:[%{public}u]", managerType_, sessionId);
53 std::string deviceName = "";
54 int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName);
55 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "get devicename err: %{public}d", ret);
56 if (managerType_ != DUP_PLAYBACK && managerType_ != DUAL_PLAYBACK) {
57 deviceName = CoreServiceHandler::GetInstance().GetAdapterNameBySessionId(sessionId);
58 }
59 if (deviceName == "") {
60 AUDIO_INFO_LOG("sink name is null");
61 deviceName = "Speaker";
62 }
63 // HpaeAdapterManager is solely responsible for creating paStream objects
64 std::shared_ptr<IRendererStream> rendererStream = CreateRendererStream(processConfig, deviceName);
65 CHECK_AND_RETURN_RET_LOG(rendererStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream!");
66 SetHighResolution(processConfig, sessionId);
67 rendererStream->SetStreamIndex(sessionId);
68 std::lock_guard<std::mutex> lock(streamMapMutex_);
69 rendererStreamMap_[sessionId] = rendererStream;
70 stream = rendererStream;
71
72 if (managerType_ == DUP_PLAYBACK || managerType_ == DUAL_PLAYBACK) {
73 AUDIO_INFO_LOG("renderer:%{public}u is DUP or DUAL, not need add to sink vecotr", sessionId);
74 return SUCCESS;
75 }
76
77 std::lock_guard<std::mutex> mutex(sinkInputsMutex_);
78 SinkInput sinkInput;
79 sinkInput.streamId = static_cast<int32_t>(sessionId);
80 sinkInput.streamType = processConfig.streamType;
81 sinkInput.uid = processConfig.appInfo.appUid;
82 sinkInput.pid = processConfig.appInfo.appPid;
83 sinkInput.paStreamId = sessionId;
84 sinkInputs_.push_back(sinkInput);
85 return SUCCESS;
86 }
87
ReleaseRender(uint32_t streamIndex)88 int32_t HpaeAdapterManager::ReleaseRender(uint32_t streamIndex)
89 {
90 AUDIO_DEBUG_LOG("Release [%{public}d] type render:[%{public}u]", managerType_, streamIndex);
91 std::unique_lock<std::mutex> lock(streamMapMutex_);
92 auto it = rendererStreamMap_.find(streamIndex);
93 if (it == rendererStreamMap_.end()) {
94 AUDIO_WARNING_LOG("No matching stream");
95 return SUCCESS;
96 }
97 std::shared_ptr<IRendererStream> currentRender = rendererStreamMap_[streamIndex];
98 rendererStreamMap_[streamIndex] = nullptr;
99 rendererStreamMap_.erase(streamIndex);
100 lock.unlock();
101
102 if (currentRender->Release() < 0) {
103 AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex);
104 return ERR_OPERATION_FAILED;
105 }
106
107 AUDIO_INFO_LOG("rendererStreamMap_.size() : %{public}zu", rendererStreamMap_.size());
108 if (rendererStreamMap_.size() == 0) {
109 AUDIO_INFO_LOG("Release the last stream");
110 }
111
112 if (isHighResolutionExist_ && highResolutionIndex_ == streamIndex) {
113 isHighResolutionExist_ = false;
114 }
115
116 if (managerType_ == DUP_PLAYBACK || managerType_ == DUAL_PLAYBACK) {
117 AUDIO_INFO_LOG("renderer:%{public}u is DUP or DUAL, not need remove", streamIndex);
118 return SUCCESS;
119 }
120
121 std::lock_guard<std::mutex> mutex(sinkInputsMutex_);
122 sinkInputs_.erase(
123 std::remove_if(sinkInputs_.begin(),
124 sinkInputs_.end(),
125 [&](const SinkInput &sinkInput) { return static_cast<uint32_t>(sinkInput.streamId) == streamIndex; }),
126 sinkInputs_.end());
127 return SUCCESS;
128 }
129
StartRender(uint32_t streamIndex)130 int32_t HpaeAdapterManager::StartRender(uint32_t streamIndex)
131 {
132 AUDIO_DEBUG_LOG("Enter StartRender");
133 std::lock_guard<std::mutex> lock(streamMapMutex_);
134 auto it = rendererStreamMap_.find(streamIndex);
135 if (it == rendererStreamMap_.end()) {
136 AUDIO_WARNING_LOG("No matching stream");
137 return SUCCESS;
138 }
139 return rendererStreamMap_[streamIndex]->Start();
140 }
141
StartRenderWithSyncId(uint32_t streamIndex,const int32_t & syncId)142 int32_t HpaeAdapterManager::StartRenderWithSyncId(uint32_t streamIndex, const int32_t &syncId)
143 {
144 AUDIO_DEBUG_LOG("Enter StartRender");
145 std::lock_guard<std::mutex> lock(streamMapMutex_);
146 auto it = rendererStreamMap_.find(streamIndex);
147 if (it == rendererStreamMap_.end()) {
148 AUDIO_WARNING_LOG("No matching stream");
149 return SUCCESS;
150 }
151 return syncId > 0 ? rendererStreamMap_[streamIndex]->StartWithSyncId(syncId) :
152 rendererStreamMap_[streamIndex]->Start();
153 }
154
StopRender(uint32_t streamIndex)155 int32_t HpaeAdapterManager::StopRender(uint32_t streamIndex)
156 {
157 AUDIO_DEBUG_LOG("Enter StopRender");
158 std::lock_guard<std::mutex> lock(streamMapMutex_);
159 auto it = rendererStreamMap_.find(streamIndex);
160 if (it == rendererStreamMap_.end()) {
161 AUDIO_WARNING_LOG("No matching stream");
162 return SUCCESS;
163 }
164 return rendererStreamMap_[streamIndex]->Stop();
165 }
166
PauseRender(uint32_t streamIndex)167 int32_t HpaeAdapterManager::PauseRender(uint32_t streamIndex)
168 {
169 AUDIO_DEBUG_LOG("Enter PauseRender");
170 std::lock_guard<std::mutex> lock(streamMapMutex_);
171 auto it = rendererStreamMap_.find(streamIndex);
172 if (it == rendererStreamMap_.end()) {
173 AUDIO_WARNING_LOG("No matching stream");
174 return SUCCESS;
175 }
176 rendererStreamMap_[streamIndex]->Pause();
177 return SUCCESS;
178 }
179
TriggerStartIfNecessary()180 int32_t HpaeAdapterManager::TriggerStartIfNecessary()
181 {
182 return SUCCESS;
183 }
184
GetStreamCount() const185 int32_t HpaeAdapterManager::GetStreamCount() const noexcept
186 {
187 if (managerType_ == RECORDER) {
188 return capturerStreamMap_.size();
189 } else {
190 return rendererStreamMap_.size();
191 }
192 }
193
GetDeviceNameForConnect(AudioProcessConfig processConfig,uint32_t sessionId,std::string & deviceName)194 int32_t HpaeAdapterManager::GetDeviceNameForConnect(AudioProcessConfig processConfig, uint32_t sessionId,
195 std::string &deviceName)
196 {
197 deviceName = "";
198 if (processConfig.audioMode == AUDIO_MODE_RECORD) {
199 if (processConfig.isWakeupCapturer) {
200 int32_t ret = CoreServiceHandler::GetInstance().SetWakeUpAudioCapturerFromAudioServer(processConfig);
201 if (ret < 0) {
202 AUDIO_ERR_LOG("ErrorCode: %{public}d", ret);
203 return ERROR;
204 }
205 deviceName = PRIMARY_WAKEUP;
206 }
207 if (processConfig.isInnerCapturer) {
208 deviceName = std::string(INNER_CAPTURER_SINK) + std::to_string(processConfig.innerCapId);
209 } else if (processConfig.capturerInfo.sourceType == SOURCE_TYPE_REMOTE_CAST) {
210 deviceName = std::string(REMOTE_CAST_INNER_CAPTURER_SINK_NAME);
211 }
212 return PolicyHandler::GetInstance().NotifyCapturerAdded(processConfig.capturerInfo,
213 processConfig.streamInfo, sessionId);
214 } else if (managerType_ == DUP_PLAYBACK) {
215 deviceName = std::string(INNER_CAPTURER_SINK) + std::to_string(processConfig.innerCapId);
216 } else if (managerType_ == DUAL_PLAYBACK) {
217 deviceName = PRO_DUAL_PLAYBACK_SINK;
218 }
219 return SUCCESS;
220 }
221
CreateCapturer(AudioProcessConfig processConfig,std::shared_ptr<ICapturerStream> & stream)222 int32_t HpaeAdapterManager::CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr<ICapturerStream> &stream)
223 {
224 AUDIO_DEBUG_LOG("Create capturer start");
225 CHECK_AND_RETURN_RET_LOG(managerType_ == RECORDER, ERROR, "Invalid managerType:%{public}d", managerType_);
226 uint32_t sessionId = processConfig.originalSessionId;
227 if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) {
228 sessionId = CoreServiceHandler::GetInstance().GenerateSessionId();
229 AUDIO_ERR_LOG("Create capturer originalSessionId is error %{public}d, get new sessionId:%{public}u",
230 processConfig.originalSessionId, sessionId);
231 }
232 processConfig.originalSessionId = sessionId;
233
234 std::string deviceName = "";
235 int32_t ret = GetDeviceNameForConnect(processConfig, processConfig.originalSessionId, deviceName);
236 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR_INVALID_PARAM, "get devicename err: %{public}d", ret);
237 SourceType &sourceType = processConfig.capturerInfo.sourceType;
238 if (sourceType != SOURCE_TYPE_PLAYBACK_CAPTURE &&
239 sourceType != SOURCE_TYPE_REMOTE_CAST &&
240 sourceType != SOURCE_TYPE_WAKEUP) {
241 deviceName = CoreServiceHandler::GetInstance().GetAdapterNameBySessionId(sessionId);
242 }
243 if (deviceName == "") {
244 AUDIO_INFO_LOG("source name is null");
245 deviceName = "Built_in_mic";
246 }
247 // HpaeAdapterManager is solely responsible for creating paStream objects
248 std::shared_ptr<ICapturerStream> capturerStream = CreateCapturerStream(processConfig, deviceName);
249 CHECK_AND_RETURN_RET_LOG(capturerStream != nullptr, ERR_DEVICE_INIT, "Failed to init pa stream");
250 capturerStream->SetStreamIndex(sessionId);
251 std::lock_guard<std::mutex> lock(streamMapMutex_);
252 capturerStreamMap_[sessionId] = capturerStream;
253 stream = capturerStream;
254 return SUCCESS;
255 }
256
AddUnprocessStream(int32_t appUid)257 int32_t HpaeAdapterManager::AddUnprocessStream(int32_t appUid)
258 {
259 std::lock_guard<std::mutex> lock(paElementsMutex_);
260 AUDIO_INFO_LOG("unprocessAppUidSet_ add appUid:%{public}d", appUid);
261 unprocessAppUidSet_.insert(appUid);
262 return SUCCESS;
263 }
264
ReleaseCapturer(uint32_t streamIndex)265 int32_t HpaeAdapterManager::ReleaseCapturer(uint32_t streamIndex)
266 {
267 AUDIO_DEBUG_LOG("Enter ReleaseCapturer");
268 std::lock_guard<std::mutex> lock(streamMapMutex_);
269 auto it = capturerStreamMap_.find(streamIndex);
270 if (it == capturerStreamMap_.end()) {
271 AUDIO_WARNING_LOG("No matching stream");
272 return SUCCESS;
273 }
274
275 if (capturerStreamMap_[streamIndex]->Release() < 0) {
276 AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex);
277 return ERR_OPERATION_FAILED;
278 }
279
280 capturerStreamMap_[streamIndex] = nullptr;
281 capturerStreamMap_.erase(streamIndex);
282 if (capturerStreamMap_.size() == 0) {
283 AUDIO_INFO_LOG("Release the last stream");
284 }
285 return SUCCESS;
286 }
287
CreateRendererStream(AudioProcessConfig processConfig,const std::string & deviceName)288 std::shared_ptr<IRendererStream> HpaeAdapterManager::CreateRendererStream(AudioProcessConfig processConfig,
289 const std::string &deviceName)
290 {
291 std::lock_guard<std::mutex> lock(paElementsMutex_);
292 bool isCallbackMode = true;
293 bool isMoveAble = true;
294 if (managerType_ == DUP_PLAYBACK) {
295 // todo check
296 processConfig.isInnerCapturer = true;
297 isMoveAble = false;
298 AUDIO_INFO_LOG("Create dup playback renderer stream");
299 } else if (managerType_ == DUAL_PLAYBACK) {
300 isCallbackMode = false;
301 isMoveAble = false;
302 }
303 std::shared_ptr<HpaeRendererStreamImpl> rendererStream =
304 std::make_shared<HpaeRendererStreamImpl>(processConfig, isMoveAble, isCallbackMode);
305 if (rendererStream->InitParams(deviceName) != SUCCESS) {
306 AUDIO_ERR_LOG("Create rendererStream failed!");
307 return nullptr;
308 }
309 return rendererStream;
310 }
311
CreateCapturerStream(AudioProcessConfig processConfig,const std::string & deviceName)312 std::shared_ptr<ICapturerStream> HpaeAdapterManager::CreateCapturerStream(AudioProcessConfig processConfig,
313 const std::string &deviceName)
314 {
315 std::lock_guard<std::mutex> lock(paElementsMutex_);
316 if (unprocessAppUidSet_.find(processConfig.appInfo.appUid) != unprocessAppUidSet_.end()) {
317 processConfig.capturerInfo.sourceType = SOURCE_TYPE_UNPROCESSED;
318 AUDIO_INFO_LOG("app uid:%{public}d sourcetype set to unprocessed", processConfig.appInfo.appUid);
319 }
320 std::shared_ptr<HpaeCapturerStreamImpl> capturerStream =
321 std::make_shared<HpaeCapturerStreamImpl>(processConfig);
322 if (capturerStream->InitParams(deviceName) != SUCCESS) {
323 AUDIO_ERR_LOG("Create capturerStream Failed, error");
324 return nullptr;
325 }
326 return capturerStream;
327 }
328
GetLatency()329 uint64_t HpaeAdapterManager::GetLatency() noexcept
330 {
331 return 0;
332 }
333
GetAllSinkInputs(std::vector<SinkInput> & sinkInputs)334 void HpaeAdapterManager::GetAllSinkInputs(std::vector<SinkInput> &sinkInputs)
335 {
336 std::lock_guard<std::mutex> lock(sinkInputsMutex_);
337 sinkInputs = sinkInputs_;
338 return;
339 }
340
SetHighResolution(AudioProcessConfig & processConfig,uint32_t sessionId)341 void HpaeAdapterManager::SetHighResolution(AudioProcessConfig &processConfig, uint32_t sessionId)
342 {
343 if (processConfig.audioMode != AUDIO_MODE_PLAYBACK) {
344 return;
345 }
346 bool spatializationEnabled = processConfig.rendererInfo.spatializationEnabled;
347 AUDIO_DEBUG_LOG("spatializationEnabled : %{public}d, isHighResolutionExist_ : %{public}d",
348 spatializationEnabled, isHighResolutionExist_);
349
350 if (spatializationEnabled == false && isHighResolutionExist_ == false && CheckHighResolution(processConfig)) {
351 AUDIO_INFO_LOG("current stream marked as high resolution");
352 isHighResolutionExist_ = true;
353 highResolutionIndex_ = sessionId;
354 } else {
355 AUDIO_INFO_LOG("current stream marked as non-high resolution");
356 }
357 }
358
CheckHighResolution(const AudioProcessConfig & processConfig) const359 bool HpaeAdapterManager::CheckHighResolution(const AudioProcessConfig &processConfig) const
360 {
361 DeviceType deviceType = processConfig.deviceType;
362 AudioStreamType streamType = processConfig.streamType;
363 AudioSamplingRate sampleRate = processConfig.streamInfo.samplingRate;
364 AudioSampleFormat sampleFormat = processConfig.streamInfo.format;
365
366 AUDIO_DEBUG_LOG("deviceType:%{public}d, streamType:%{public}d, sampleRate:%{public}d, sampleFormat:%{public}d",
367 deviceType, streamType, sampleRate, sampleFormat);
368
369 if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP && streamType == STREAM_MUSIC &&
370 sampleRate >= SAMPLE_RATE_48000 && sampleFormat >= SAMPLE_S24LE) {
371 return true;
372 }
373 return false;
374 }
375 } // namespace AudioStandard
376 } // namespace OHOS
377