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