• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #ifndef LOG_TAG
17 #define LOG_TAG "HpaeRendererManager"
18 #endif
19 
20 #include "hpae_renderer_manager.h"
21 #include "audio_stream_info.h"
22 #include "audio_errors.h"
23 #include "hpae_node_common.h"
24 #include "audio_effect_chain_manager.h"
25 #include "audio_utils.h"
26 #include "audio_volume.h"
27 #include "audio_engine_log.h"
28 #include "hpae_output_cluster.h"
29 #include "hpae_remote_output_cluster.h"
30 
31 constexpr int32_t DEFAULT_EFFECT_RATE = 48000;
32 constexpr int32_t DEFAULT_EFFECT_FRAME_LEN = 960;
33 
34 namespace OHOS {
35 namespace AudioStandard {
36 namespace HPAE {
37 
HpaeRendererManager(HpaeSinkInfo & sinkInfo)38 HpaeRendererManager::HpaeRendererManager(HpaeSinkInfo &sinkInfo)
39     : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo)
40 {}
41 
~HpaeRendererManager()42 HpaeRendererManager::~HpaeRendererManager()
43 {
44     AUDIO_INFO_LOG("destructor renderer");
45     if (isInit_.load()) {
46         DeInit();
47     }
48 }
49 
IsMchDevice()50 bool HpaeRendererManager::IsMchDevice()
51 {
52     return sinkInfo_.deviceName == "MCH_Speaker" || sinkInfo_.deviceName == "DP_MCH_speaker";
53 }
54 
CreateInputSession(const HpaeStreamInfo & streamInfo)55 int32_t HpaeRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo)
56 {
57     Trace trace("[" + std::to_string(streamInfo.sessionId) + "]HpaeRendererManager::CreateInputSession");
58     HpaeNodeInfo nodeInfo;
59     nodeInfo.channels = streamInfo.channels;
60     nodeInfo.format = streamInfo.format;
61     nodeInfo.frameLen = streamInfo.frameLen;
62     nodeInfo.channelLayout = (AudioChannelLayout)streamInfo.channelLayout;
63     nodeInfo.streamType = streamInfo.streamType;
64     nodeInfo.sessionId = streamInfo.sessionId;
65     nodeInfo.samplingRate = static_cast<AudioSamplingRate>(streamInfo.samplingRate);
66     nodeInfo.sceneType = TransToProperSceneType(streamInfo.effectInfo.streamUsage, streamInfo.effectInfo.effectScene);
67     nodeInfo.effectInfo = streamInfo.effectInfo;
68     TransNodeInfoForCollaboration(nodeInfo, isCollaborationEnabled_);
69     nodeInfo.fadeType = streamInfo.fadeType;
70     nodeInfo.statusCallback = weak_from_this();
71     nodeInfo.deviceClass = sinkInfo_.deviceClass;
72     nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
73     sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared<HpaeSinkInputNode>(nodeInfo);
74     sinkInputNodeMap_[streamInfo.sessionId]->SetAppUid(streamInfo.uid);
75     AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d",
76         nodeInfo.streamType,
77         nodeInfo.sessionId,
78         nodeInfo.sceneType);
79     CreateProcessCluster(nodeInfo);
80     if (!sessionNodeMap_[nodeInfo.sessionId].bypass) {
81         CHECK_AND_RETURN_RET_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType), ERROR,
82             "could not find processorType %{public}d", nodeInfo.sceneType);
83         sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
84         int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
85         if (ret != SUCCESS) {
86             AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret);
87         }
88     }
89     return SUCCESS;
90 }
91 
AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node)92 int32_t HpaeRendererManager::AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node)
93 {
94     auto request = [this, node]() { AddSingleNodeToSink(node); };
95     SendRequest(request);
96     return SUCCESS;
97 }
98 
AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node,bool isConnect)99 void HpaeRendererManager::AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node, bool isConnect)
100 {
101     Trace trace("HpaeRendererManager::AddSingleNodeToSink");
102     HpaeNodeInfo nodeInfo = node->GetNodeInfo();
103     nodeInfo.deviceClass = sinkInfo_.deviceClass;
104     nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
105     // no need history buffer in not offload sink
106     nodeInfo.historyFrameCount = 0;
107     nodeInfo.statusCallback = weak_from_this();
108     nodeInfo.sceneType = TransToProperSceneType(nodeInfo.effectInfo.streamUsage, nodeInfo.effectInfo.effectScene);
109     // for collaboration
110     TransNodeInfoForCollaboration(nodeInfo, isCollaborationEnabled_);
111     node->SetNodeInfo(nodeInfo);
112     uint32_t sessionId = nodeInfo.sessionId;
113 
114     sinkInputNodeMap_[sessionId] = node;
115     SetSessionState(sessionId, node->GetState());
116     sessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType;
117 
118     AUDIO_INFO_LOG("[FinishMove] session :%{public}u to sink:%{public}s, sceneType is %{public}d",
119         sessionId, sinkInfo_.deviceClass.c_str(), nodeInfo.sceneType);
120     CreateEffectAndConnect(nodeInfo, isConnect);
121 }
122 
CreateEffectAndConnect(HpaeNodeInfo & nodeInfo,bool isConnect)123 void HpaeRendererManager::CreateEffectAndConnect(HpaeNodeInfo &nodeInfo, bool isConnect)
124 {
125     uint32_t sessionId = nodeInfo.sessionId;
126     HpaeNodeInfo processNodeInfo = nodeInfo;
127     processNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE;
128     processNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN;
129     processNodeInfo.channels = STEREO;
130     processNodeInfo.channelLayout = CH_LAYOUT_STEREO;
131     CreateProcessCluster(processNodeInfo);
132     if (!sessionNodeMap_[sessionId].bypass) {
133         CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
134             "could not find processorType %{public}d", nodeInfo.sceneType);
135         sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
136         int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
137         if (ret != SUCCESS) {
138             AUDIO_WARNING_LOG("session:%{public}u update audio effect when creating failed ret %{public}d",
139                 sessionId, ret);
140         }
141     }
142 
143     CHECK_AND_RETURN_LOG(isConnect == true, "not need connect session:%{public}d", sessionId);
144     if (sessionNodeMap_[sessionId].state == HPAE_SESSION_RUNNING) {
145         AUDIO_INFO_LOG("session:%{public}u connect to sink:%{public}s",
146             sessionId, sinkInfo_.deviceClass.c_str());
147         ConnectInputSession(sessionId);
148     }
149 }
150 
CreateDefaultProcessCluster(HpaeNodeInfo & nodeInfo)151 void HpaeRendererManager::CreateDefaultProcessCluster(HpaeNodeInfo &nodeInfo)
152 {
153     AUDIO_INFO_LOG("use default processCluster");
154     if (sceneClusterMap_.find(HPAE_SCENE_DEFAULT) == sceneClusterMap_.end()) {
155         AUDIO_INFO_LOG("default processCluster is null, create default processCluster");
156         HpaeNodeInfo temp = nodeInfo;
157         temp.sceneType = HPAE_SCENE_DEFAULT;
158         auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(temp, sinkInfo_);
159         sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster;
160         sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster;
161         sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
162     } else {
163         sceneClusterMap_[nodeInfo.sceneType] = sceneClusterMap_[HPAE_SCENE_DEFAULT];
164         sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
165     }
166     return;
167 }
168 
CreateProcessClusterInner(HpaeNodeInfo & nodeInfo,int32_t processClusterDecision)169 void HpaeRendererManager::CreateProcessClusterInner(HpaeNodeInfo &nodeInfo, int32_t processClusterDecision)
170 {
171     HpaeNodeInfo temp = nodeInfo;
172     std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster = nullptr;
173     switch (processClusterDecision) {
174         case NO_NEED_TO_CREATE_PROCESSCLUSTER:
175             AUDIO_INFO_LOG("no need to create processCluster");
176             CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
177             AUDIO_INFO_LOG("processCluster is null, create a new processCluster");
178             sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
179             break;
180         case CREATE_NEW_PROCESSCLUSTER:
181             CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
182             AUDIO_INFO_LOG("create new processCluster");
183             sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
184             break;
185         case CREATE_DEFAULT_PROCESSCLUSTER:
186             temp.sceneType = HPAE_SCENE_DEFAULT;
187             if (!SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT)) {
188                 AUDIO_INFO_LOG("begin control, create default processCluster");
189                 hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(temp, sinkInfo_);
190                 sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster;
191                 sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster;
192             } else {
193                 sceneClusterMap_[nodeInfo.sceneType] = sceneClusterMap_[HPAE_SCENE_DEFAULT];
194             }
195             sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
196             break;
197         case USE_DEFAULT_PROCESSCLUSTER:
198             CreateDefaultProcessCluster(nodeInfo);
199             break;
200         case USE_NONE_PROCESSCLUSTER:
201             AUDIO_INFO_LOG("use none processCluster");
202             break;
203         case CREATE_EXTRA_PROCESSCLUSTER:
204             AUDIO_INFO_LOG("out of control");
205             CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
206             AUDIO_INFO_LOG("out of control, create a new processCluster");
207             sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
208             break;
209         default:
210             break;
211     }
212     sessionNodeMap_[nodeInfo.sessionId].bypass = (processClusterDecision == USE_NONE_PROCESSCLUSTER) ? true : false;
213     return;
214 }
215 
CreateProcessCluster(HpaeNodeInfo & nodeInfo)216 void HpaeRendererManager::CreateProcessCluster(HpaeNodeInfo &nodeInfo)
217 {
218     Trace trace("HpaeRendererManager::CreateProcessCluster");
219     std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType);
220     int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType);
221     CreateProcessClusterInner(nodeInfo, processClusterDecision);
222 }
223 
AddAllNodesToSink(const std::vector<std::shared_ptr<HpaeSinkInputNode>> & sinkInputs,bool isConnect)224 int32_t HpaeRendererManager::AddAllNodesToSink(
225     const std::vector<std::shared_ptr<HpaeSinkInputNode>> &sinkInputs, bool isConnect)
226 {
227     auto request = [this, sinkInputs, isConnect]() {
228         for (const auto &it : sinkInputs) {
229             AddSingleNodeToSink(it, isConnect);
230         }
231     };
232     SendRequest(request);
233     return SUCCESS;
234 }
235 
TransToProperSceneType(StreamUsage streamUsage,AudioEffectScene effectScene)236 HpaeProcessorType HpaeRendererManager::TransToProperSceneType(StreamUsage streamUsage, AudioEffectScene effectScene)
237 {
238     if (sinkInfo_.lib == "libmodule-split-stream-sink.z.so") {
239         return TransStreamUsageToSplitSceneType(streamUsage, sinkInfo_.splitMode);
240     } else if (sinkInfo_.deviceClass == "remote" || IsMchDevice()) {
241         return HPAE_SCENE_EFFECT_NONE;
242     } else {
243         return TransEffectSceneToSceneType(effectScene);
244     }
245 }
246 
GetProcessorType(uint32_t sessionId)247 HpaeProcessorType HpaeRendererManager::GetProcessorType(uint32_t sessionId)
248 {
249     HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
250     if ((sessionNodeMap_[sessionId].bypass || nodeInfo.effectInfo.effectMode == EFFECT_NONE) &&
251         (!isSplitProcessorType(nodeInfo.sceneType))) {
252             return HPAE_SCENE_EFFECT_NONE;
253     }
254     return nodeInfo.sceneType;
255 }
256 
RefreshProcessClusterByDeviceInner(const std::shared_ptr<HpaeSinkInputNode> & node)257 void HpaeRendererManager::RefreshProcessClusterByDeviceInner(const std::shared_ptr<HpaeSinkInputNode> &node)
258 {
259     CHECK_AND_RETURN_LOG(node != nullptr, "sinkInputNode is nullptr");
260     HpaeNodeInfo nodeInfo = node->GetNodeInfo();
261     std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType);
262     int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType);
263     bool isConnected = (node->isConnected_) ? true : false;
264     if (processClusterDecision != USE_NONE_PROCESSCLUSTER && sessionNodeMap_[nodeInfo.sessionId].bypass) {
265         DeleteConnectInputProcessor(sinkInputNodeMap_[nodeInfo.sessionId]);
266         DeleteProcessCluster(GetProcessorType(nodeInfo.sessionId));
267         CreateProcessClusterInner(nodeInfo, processClusterDecision);
268         CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
269             "could not find processorType %{public}d", nodeInfo.sceneType);
270         sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
271         sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
272         if (isConnected) {
273             ConnectInputSession(nodeInfo.sessionId);
274         }
275     } else if (processClusterDecision == USE_NONE_PROCESSCLUSTER && !sessionNodeMap_[nodeInfo.sessionId].bypass) {
276         DeleteConnectInputProcessor(sinkInputNodeMap_[nodeInfo.sessionId]);
277         DeleteProcessCluster(GetProcessorType(nodeInfo.sessionId));
278         sessionNodeMap_[nodeInfo.sessionId].bypass = true;
279         if (isConnected) {
280             ConnectInputSession(nodeInfo.sessionId);
281         }
282     }
283 }
284 
RefreshProcessClusterByDevice()285 int32_t HpaeRendererManager::RefreshProcessClusterByDevice()
286 {
287     auto request = [this]() {
288         for (const auto &it : sinkInputNodeMap_) {
289             RefreshProcessClusterByDeviceInner(it.second);
290         }
291     };
292     SendRequest(request);
293     return SUCCESS;
294 }
295 
CreateStream(const HpaeStreamInfo & streamInfo)296 int32_t HpaeRendererManager::CreateStream(const HpaeStreamInfo &streamInfo)
297 {
298     if (!IsInit()) {
299         return ERR_INVALID_OPERATION;
300     }
301     auto request = [this, streamInfo]() {
302         Trace trace("HpaeRendererManager::CreateStream id[" +
303             std::to_string(streamInfo.sessionId) + "]");
304         AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s",
305             streamInfo.sessionId,
306             sinkInfo_.deviceName.c_str());
307         CreateInputSession(streamInfo);
308         SetSessionState(streamInfo.sessionId, HPAE_SESSION_PREPARED);
309         sessionNodeMap_[streamInfo.sessionId].isMoveAble = streamInfo.isMoveAble;
310         sinkInputNodeMap_[streamInfo.sessionId]->SetState(HPAE_SESSION_PREPARED);
311     };
312     SendRequest(request);
313     return SUCCESS;
314 }
315 
DestroyStream(uint32_t sessionId)316 int32_t HpaeRendererManager::DestroyStream(uint32_t sessionId)
317 {
318     if (!IsInit()) {
319         return ERR_INVALID_OPERATION;
320     }
321     auto request = [this, sessionId]() {
322         Trace trace("HpaeRendererManager::DestroyStream id[" +
323             std::to_string(sessionId) + "]");
324         AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId);
325         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
326             "Release not find sessionId %{public}u", sessionId);
327         SetSessionState(sessionId, HPAE_SESSION_RELEASED);
328         sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RELEASED);
329         DeleteInputSession(sessionId);
330     };
331     SendRequest(request);
332     return SUCCESS;
333 }
334 
DeleteConnectInputProcessor(const std::shared_ptr<HpaeSinkInputNode> & sinkInputNode)335 int32_t HpaeRendererManager::DeleteConnectInputProcessor(
336     const std::shared_ptr<HpaeSinkInputNode> &sinkInputNode)
337 {
338     uint32_t sessionId = sinkInputNode->GetSessionId();
339     HpaeNodeInfo nodeInfo = sinkInputNode->GetNodeInfo();
340     HpaeProcessorType sceneType = GetProcessorType(sessionId);
341     if (SafeGetMap(sceneClusterMap_, sceneType)) {
342         DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
343     }
344     return SUCCESS;
345 }
346 
DeleteInputSession(uint32_t sessionId)347 int32_t HpaeRendererManager::DeleteInputSession(uint32_t sessionId)
348 {
349     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSession");
350     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
351         AUDIO_INFO_LOG("could not find session:%{public}d", sessionId);
352         return SUCCESS;
353     }
354     DeleteConnectInputProcessor(sinkInputNodeMap_[sessionId]);
355     sinkInputNodeMap_.erase(sessionId);
356     sessionNodeMap_.erase(sessionId);
357     return SUCCESS;
358 }
359 
360 
DeleteInputSessionForMove(uint32_t sessionId)361 int32_t HpaeRendererManager::DeleteInputSessionForMove(uint32_t sessionId)
362 {
363     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSessionForMove");
364     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
365         AUDIO_INFO_LOG("could not find session:%{public}d", sessionId);
366         return SUCCESS;
367     }
368     HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
369     HpaeProcessorType sceneType = GetProcessorType(sessionId);
370     if (SafeGetMap(sceneClusterMap_, sceneType)) {
371         DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
372         if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) {
373             sceneClusterMap_[sceneType]->DisConnectMixerNode();
374             outputCluster_->DisConnect(sceneClusterMap_[sceneType]);
375             // for collaboration
376             if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
377                 hpaeCoBufferNode_->DisConnect(sceneClusterMap_[sceneType]);
378                 TriggerCallback(DISCONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
379             }
380             sceneClusterMap_[sceneType]->SetConnectedFlag(false);
381         }
382     }
383     DeleteProcessCluster(sceneType);
384     sinkInputNodeMap_.erase(sessionId);
385     sessionNodeMap_.erase(sessionId);
386     return SUCCESS;
387 }
388 
DisConnectProcessCluster(const HpaeNodeInfo & nodeInfo,HpaeProcessorType sceneType,uint32_t sessionId)389 void HpaeRendererManager::DisConnectProcessCluster(
390     const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId)
391 {
392     Trace trace("[" + std::to_string(sessionId) +
393         "]HpaeRendererManager::DisConnectProcessCluster sceneType:" + std::to_string(sceneType));
394     if (!sessionNodeMap_[sessionId].bypass) {
395         CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
396             "could not find processorType %{public}d", nodeInfo.sceneType);
397         sceneClusterMap_[nodeInfo.sceneType]->AudioRendererRelease(sinkInputNodeMap_[sessionId]->GetNodeInfo());
398     }
399     sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]);
400     sinkInputNodeMap_[sessionId]->isConnected_ = false;
401     if (!sessionNodeMap_[sessionId].bypass) {
402         sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]--;
403         if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_DEFAULT]) {
404             sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]--;
405         }
406         AUDIO_INFO_LOG("sceneType %{public}d is deleted, current count: %{public}d, default count: %{public}d",
407             nodeInfo.sceneType, sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType],
408             sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]);
409     }
410 }
411 
DeleteProcessCluster(HpaeProcessorType sceneType)412 int32_t HpaeRendererManager::DeleteProcessCluster(HpaeProcessorType sceneType)
413 {
414     if (sceneTypeToProcessClusterCountMap_[sceneType] == 0) {
415         sceneClusterMap_.erase(sceneType);
416         sceneTypeToProcessClusterCountMap_.erase(sceneType);
417     }
418     if (sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT] == 0) {
419         sceneClusterMap_.erase(HPAE_SCENE_DEFAULT);
420         sceneTypeToProcessClusterCountMap_.erase(HPAE_SCENE_DEFAULT);
421     }
422     return SUCCESS;
423 }
424 
isSplitProcessorType(HpaeProcessorType sceneType)425 bool HpaeRendererManager::isSplitProcessorType(HpaeProcessorType sceneType)
426 {
427     if (sceneType == HPAE_SCENE_SPLIT_MEDIA || sceneType == HPAE_SCENE_SPLIT_NAVIGATION ||
428         sceneType == HPAE_SCENE_SPLIT_COMMUNICATION) {
429         return true;
430     }
431     return false;
432 }
433 
ConnectInputSession(uint32_t sessionId)434 int32_t HpaeRendererManager::ConnectInputSession(uint32_t sessionId)
435 {
436     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectInputSession");
437     AUDIO_INFO_LOG("connect input session:%{public}d", sessionId);
438     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
439         AUDIO_INFO_LOG("could not input node by sessionid:%{public}d", sessionId);
440         return ERR_INVALID_PARAM;
441     }
442     if (sinkInputNodeMap_[sessionId]->GetState() != HPAE_SESSION_RUNNING) {
443         return SUCCESS;
444     }
445     HpaeProcessorType sceneType = GetProcessorType(sessionId);
446     if (SafeGetMap(sceneClusterMap_, sceneType)) {
447         ConnectProcessCluster(sessionId, sceneType);
448     }
449     if (outputCluster_->GetState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
450         outputCluster_->Start();
451     }
452     return SUCCESS;
453 }
454 
ConnectProcessCluster(uint32_t sessionId,HpaeProcessorType sceneType)455 void HpaeRendererManager::ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType)
456 {
457     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectProcessCluster sceneType:"
458         + std::to_string(sceneType));
459     HpaeProcessorType tmpSceneType = (sceneClusterMap_[sceneType] == SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT))
460         ? HPAE_SCENE_DEFAULT : sceneType;
461     if (toBeStoppedSceneTypeToSessionMap_.count(tmpSceneType) > 0) {
462         uint32_t sessionIdToStop = toBeStoppedSceneTypeToSessionMap_[tmpSceneType];
463         if (sessionIdToStop == sessionId) {
464             toBeStoppedSceneTypeToSessionMap_.erase(tmpSceneType);
465         } else {
466             if (SafeGetMap(sinkInputNodeMap_, sessionIdToStop)) {
467                 sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionIdToStop]->GetNodeInfo());
468             }
469             toBeStoppedSceneTypeToSessionMap_.erase(tmpSceneType);
470             int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo());
471             if (ret != SUCCESS) {
472                 AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret);
473             }
474         }
475     } else {
476         int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo());
477         if (ret != SUCCESS) {
478             AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret);
479         }
480     }
481     if (!outputCluster_->IsProcessClusterConnected(sceneType) && !sceneClusterMap_[sceneType]->GetConnectedFlag()) {
482         outputCluster_->Connect(sceneClusterMap_[sceneType]);
483         sceneClusterMap_[sceneType]->SetConnectedFlag(true);
484     }
485     sceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]);
486     sinkInputNodeMap_[sessionId]->isConnected_ = true;
487     if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
488         uint32_t latency = outputCluster_->GetLatency();
489         hpaeCoBufferNode_->SetLatency(latency);
490         hpaeCoBufferNode_->Connect(sceneClusterMap_[sceneType]);
491         TriggerCallback(CONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
492     }
493     std::shared_ptr<HpaeSinkInputNode> sinkInputNode = SafeGetMap(sinkInputNodeMap_, sessionId);
494     CHECK_AND_RETURN_LOG(sinkInputNode != nullptr, "sinkInputNode is nullptr");
495     sceneClusterMap_[sceneType]->SetLoudnessGain(sessionId, sinkInputNode->GetLoudnessGain());
496 }
497 
MoveAllStreamToNewSink(const std::string & sinkName,const std::vector<uint32_t> & moveIds,MoveSessionType moveType)498 void HpaeRendererManager::MoveAllStreamToNewSink(const std::string &sinkName,
499     const std::vector<uint32_t>& moveIds, MoveSessionType moveType)
500 {
501     Trace trace("HpaeRendererManager::MoveAllStreamToNewSink[" + sinkName + "]");
502     std::string name = sinkName;
503     std::vector<std::shared_ptr<HpaeSinkInputNode>> sinkInputs;
504     std::vector<uint32_t> sessionIds;
505     std::string idStr;
506     for (const auto &it : sinkInputNodeMap_) {
507         if (moveType == MOVE_ALL || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) {
508             sinkInputs.emplace_back(it.second);
509             sessionIds.emplace_back(it.first);
510             idStr.append("[").append(std::to_string(it.first)).append("],");
511         }
512     }
513     for (const auto &it : sessionIds) {
514         DeleteInputSessionForMove(it);
515     }
516     AUDIO_INFO_LOG("[StartMove] session:%{public}s to sink name:%{public}s, move type:%{public}d",
517         idStr.c_str(), name.c_str(), moveType);
518     TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name, moveType);
519 }
520 
MoveAllStream(const std::string & sinkName,const std::vector<uint32_t> & sessionIds,MoveSessionType moveType)521 int32_t HpaeRendererManager::MoveAllStream(const std::string &sinkName, const std::vector<uint32_t>& sessionIds,
522     MoveSessionType moveType)
523 {
524     if (!IsInit()) {
525         AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str());
526         MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
527     } else {
528         AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str());
529         auto request = [this, sinkName, sessionIds, moveType]() {
530             MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
531         };
532         SendRequest(request);
533     }
534     return SUCCESS;
535 }
536 
MoveStreamSync(uint32_t sessionId,const std::string & sinkName)537 void HpaeRendererManager::MoveStreamSync(uint32_t sessionId, const std::string &sinkName)
538 {
539     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
540         AUDIO_ERR_LOG("[StartMove] session:%{public}u failed,can not find session,move %{public}s --> %{public}s",
541             sessionId, sinkInfo_.deviceName.c_str(), sinkName.c_str());
542         TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
543         return;
544     }
545 
546     if (sinkName.empty()) {
547         AUDIO_ERR_LOG("[StartMove] session:%{public}u failed,sinkName is empty", sessionId);
548         TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
549         return;
550     }
551 
552     AUDIO_INFO_LOG("[StartMove] session: %{public}u,sink [%{public}s] --> [%{public}s]",
553         sessionId, sinkInfo_.deviceName.c_str(), sinkName.c_str());
554     std::shared_ptr<HpaeSinkInputNode> inputNode = sinkInputNodeMap_[sessionId];
555     HpaeSessionState inputState = inputNode->GetState();
556     if (inputState == HPAE_SESSION_STOPPING || inputState == HPAE_SESSION_PAUSING) {
557         HpaeSessionState state = inputState == HPAE_SESSION_PAUSING ? HPAE_SESSION_PAUSED : HPAE_SESSION_STOPPED;
558         IOperation operation = inputState == HPAE_SESSION_PAUSING ? OPERATION_PAUSED : OPERATION_STOPPED;
559         SetSessionState(sessionId, state);
560         inputNode->SetState(state);
561         TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
562         // todo: do fade out
563     }
564     DeleteInputSessionForMove(sessionId);
565     std::string name = sinkName;
566     TriggerCallback(MOVE_SINK_INPUT, inputNode, name);
567 }
568 
MoveStream(uint32_t sessionId,const std::string & sinkName)569 int32_t HpaeRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName)
570 {
571     if (!IsInit()) {
572         MoveStreamSync(sessionId, sinkName);
573     } else {
574         auto request = [this, sessionId, sinkName]() { MoveStreamSync(sessionId, sinkName); };
575         SendRequest(request);
576     }
577     return SUCCESS;
578 }
579 
Start(uint32_t sessionId)580 int32_t HpaeRendererManager::Start(uint32_t sessionId)
581 {
582     auto request = [this, sessionId]() {
583         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Start");
584         AUDIO_INFO_LOG("Start sessionId %{public}u, deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
585         if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
586             sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RUNNING);
587         }
588         HandlePriPaPower(sessionId);
589         ConnectInputSession(sessionId);
590         SetSessionState(sessionId, HPAE_SESSION_RUNNING);
591         SetSessionFade(sessionId, OPERATION_STARTED);
592     };
593     SendRequest(request);
594     return SUCCESS;
595 }
596 
StartWithSyncId(uint32_t sessionId,int32_t syncId)597 int32_t HpaeRendererManager::StartWithSyncId(uint32_t sessionId, int32_t syncId)
598 {
599     auto request = [this, sessionId, syncId]() {
600         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::StartWithSyncId");
601         AUDIO_INFO_LOG("StartWithSyncId sessionId %{public}u, deviceName %{public}s",
602             sessionId, sinkInfo_.deviceName.c_str());
603         if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
604             sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RUNNING);
605         }
606         HandlePriPaPower(sessionId);
607         ConnectInputSession(sessionId);
608         SetSessionState(sessionId, HPAE_SESSION_RUNNING);
609         SetSessionFade(sessionId, OPERATION_STARTED);
610         if (syncId >= 0) {
611             HandleSyncId(sessionId, syncId);
612         }
613     };
614     SendRequest(request);
615     return SUCCESS;
616 }
617 
DisConnectInputSession(uint32_t sessionId)618 int32_t HpaeRendererManager::DisConnectInputSession(uint32_t sessionId)
619 {
620     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
621         AUDIO_INFO_LOG("DisConnectInputSession sessionId %{public}u", sessionId);
622         return SUCCESS;
623     }
624     HpaeProcessorType sceneType = GetProcessorType(sessionId);
625     if (SafeGetMap(sceneClusterMap_, sceneType)) {
626         DisConnectInputCluster(sessionId, sceneType);
627     }
628     return SUCCESS;
629 }
630 
OnDisConnectProcessCluster(HpaeProcessorType sceneType)631 void HpaeRendererManager::OnDisConnectProcessCluster(HpaeProcessorType sceneType)
632 {
633     auto request = [this, sceneType]() {
634         AUDIO_INFO_LOG("mixerNode trigger callback, sceneType %{public}d", sceneType);
635         if (SafeGetMap(sceneClusterMap_, sceneType) && sceneClusterMap_[sceneType]->GetPreOutNum() == 0) {
636             sceneClusterMap_[sceneType]->DisConnectMixerNode();
637             // for collaboration
638             if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
639                 hpaeCoBufferNode_->DisConnect(sceneClusterMap_[sceneType]);
640                 TriggerCallback(DISCONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
641             }
642             outputCluster_->DisConnect(sceneClusterMap_[sceneType]);
643             sceneClusterMap_[sceneType]->SetConnectedFlag(false);
644             if (toBeStoppedSceneTypeToSessionMap_.count(sceneType) &&
645                 SafeGetMap(sinkInputNodeMap_, toBeStoppedSceneTypeToSessionMap_[sceneType])) {
646                 sceneClusterMap_[sceneType]->
647                     AudioRendererStop(sinkInputNodeMap_[toBeStoppedSceneTypeToSessionMap_[sceneType]]->GetNodeInfo());
648             }
649             toBeStoppedSceneTypeToSessionMap_.erase(sceneType);
650         }
651         DeleteProcessCluster(sceneType);
652     };
653     SendRequest(request);
654 }
655 
DisConnectInputCluster(uint32_t sessionId,HpaeProcessorType sceneType)656 void HpaeRendererManager::DisConnectInputCluster(uint32_t sessionId, HpaeProcessorType sceneType)
657 {
658     sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]);
659     sinkInputNodeMap_[sessionId]->isConnected_ = false;
660     if (sceneClusterMap_[sceneType]->GetPreOutNum() > 0) {
661         int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionId]->GetNodeInfo());
662         if (ret != SUCCESS) {
663             AUDIO_WARNING_LOG("update audio effect when stopping failed, ret = %{public}d", ret);
664         }
665     } else {
666         HpaeProcessorType tmpSceneType = (sceneClusterMap_[sceneType] ==
667             SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT)) ? HPAE_SCENE_DEFAULT : sceneType;
668         CHECK_AND_RETURN_LOG(toBeStoppedSceneTypeToSessionMap_.count(sceneType) == 0,
669             "sessionId %{public}d to stop already existed", sessionId);
670         toBeStoppedSceneTypeToSessionMap_[tmpSceneType] = sessionId;
671         AUDIO_INFO_LOG("sessionId %{public}u will be stop", sessionId);
672     }
673 }
674 
SetSessionState(uint32_t sessionId,HpaeSessionState renderState)675 void HpaeRendererManager::SetSessionState(uint32_t sessionId, HpaeSessionState renderState)
676 {
677     sessionNodeMap_[sessionId].state = renderState;
678 }
679 
Pause(uint32_t sessionId)680 int32_t HpaeRendererManager::Pause(uint32_t sessionId)
681 {
682     auto request = [this, sessionId]() {
683         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Pause");
684         AUDIO_INFO_LOG("Pause sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
685         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
686             "Pause not find sessionId %{public}u", sessionId);
687         if (!SetSessionFade(sessionId, OPERATION_PAUSED)) {
688             DisConnectInputSession(sessionId);
689         }
690     };
691     SendRequest(request);
692     return SUCCESS;
693 }
694 
Flush(uint32_t sessionId)695 int32_t HpaeRendererManager::Flush(uint32_t sessionId)
696 {
697     auto request = [this, sessionId]() {
698         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Flush");
699         AUDIO_INFO_LOG("Flush sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
700         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
701             "Flush not find sessionId %{public}u", sessionId);
702         // flush history buffer
703         sinkInputNodeMap_[sessionId]->Flush();
704         HpaeProcessorType sceneType = GetProcessorType(sessionId);
705         CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, sceneType),
706             "Flush not find sceneType: %{public}d in sceneClusterMap", static_cast<int32_t>(sceneType));
707         sceneClusterMap_[sceneType]->InitEffectBuffer(sessionId);
708     };
709     SendRequest(request);
710     return SUCCESS;
711 }
712 
Drain(uint32_t sessionId)713 int32_t HpaeRendererManager::Drain(uint32_t sessionId)
714 {
715     auto request = [this, sessionId]() {
716         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Drain");
717         AUDIO_INFO_LOG("Drain sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str());
718         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
719             "Drain not find sessionId %{public}u", sessionId);
720         sinkInputNodeMap_[sessionId]->Drain();
721         if (sessionNodeMap_[sessionId].state != HPAE_SESSION_RUNNING) {
722             AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId);
723             TriggerCallback(UPDATE_STATUS,
724                 HPAE_STREAM_CLASS_TYPE_PLAY,
725                 sessionId,
726                 sessionNodeMap_[sessionId].state,
727                 OPERATION_DRAINED);
728         }
729     };
730     SendRequest(request);
731     return SUCCESS;
732 }
733 
Stop(uint32_t sessionId)734 int32_t HpaeRendererManager::Stop(uint32_t sessionId)
735 {
736     auto request = [this, sessionId]() {
737         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Stop");
738         AUDIO_INFO_LOG("Stop sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str());
739         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
740             "Stop not find sessionId %{public}u", sessionId);
741         if (!SetSessionFade(sessionId, OPERATION_STOPPED)) {
742             DisConnectInputSession(sessionId);
743         }
744     };
745     SendRequest(request);
746     return SUCCESS;
747 }
748 
Release(uint32_t sessionId)749 int32_t HpaeRendererManager::Release(uint32_t sessionId)
750 {
751     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Release");
752     CHECK_AND_RETURN_RET_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), ERROR,
753         "Release not find sessionId %{public}u", sessionId);
754     return DestroyStream(sessionId);
755 }
756 
CheckIsStreamRunning()757 bool HpaeRendererManager::CheckIsStreamRunning()
758 {
759     bool isRunning = false;
760     for (const auto& it : sessionNodeMap_) {
761         if (it.second.state == HPAE_SESSION_RUNNING) {
762             isRunning = true;
763             break;
764         }
765     }
766     return isRunning;
767 }
768 
SuspendStreamManager(bool isSuspend)769 int32_t HpaeRendererManager::SuspendStreamManager(bool isSuspend)
770 {
771     Trace trace("HpaeRendererManager::SuspendStreamManager: " + std::to_string(isSuspend));
772     auto request = [this, isSuspend]() {
773         if (isSuspend_ == isSuspend) {
774             return;
775         }
776         AUDIO_INFO_LOG("suspend audio device: %{public}s, isSuspend: %{public}d",
777             sinkInfo_.deviceName.c_str(), isSuspend);
778         isSuspend_ = isSuspend;
779         if (isSuspend_) {
780             if (outputCluster_ != nullptr) {
781                 outputCluster_->Stop();
782             }
783         } else if (outputCluster_ != nullptr && outputCluster_->GetState() != STREAM_MANAGER_RUNNING &&
784             CheckIsStreamRunning()) {
785             outputCluster_->Start();
786         }
787     };
788     SendRequest(request);
789     return SUCCESS;
790 }
791 
SetMute(bool isMute)792 int32_t HpaeRendererManager::SetMute(bool isMute)
793 {
794     // to do check pulseaudio
795     auto request = [this, isMute]() {
796         if (isMute_ != isMute) {
797             isMute_ = isMute;  // todo: fadein and fadeout and mute feature
798         }
799     };
800     SendRequest(request);
801     return SUCCESS;
802 }
803 
HandleMsg()804 void HpaeRendererManager::HandleMsg()
805 {
806     hpaeNoLockQueue_.HandleRequests();
807 }
808 
ReloadRenderManager(const HpaeSinkInfo & sinkInfo,bool isReload)809 int32_t HpaeRendererManager::ReloadRenderManager(const HpaeSinkInfo &sinkInfo, bool isReload)
810 {
811     if (IsInit()) {
812         AUDIO_INFO_LOG("deinit:%{public}s renderer first.", sinkInfo.deviceName.c_str());
813         DeInit();
814     }
815     hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
816     auto request = [this, sinkInfo, isReload]() {
817         AUDIO_INFO_LOG("ReloadRenderManager deviceName %{public}s", sinkInfo.deviceName.c_str());
818 
819         for (const auto &it : sinkInputNodeMap_) {
820             DeleteConnectInputProcessor(it.second);
821         }
822         AUDIO_INFO_LOG("delete device:%{public}s all input processor end", sinkInfo.deviceName.c_str());
823         sinkInfo_ = sinkInfo;
824         InitManager(isReload);
825         AUDIO_INFO_LOG("init device:%{public}s manager end", sinkInfo.deviceName.c_str());
826         for (const auto &it : sinkInputNodeMap_) {
827             HpaeNodeInfo nodeInfo = it.second->GetNodeInfo();
828             CreateEffectAndConnect(nodeInfo);
829         }
830         AUDIO_INFO_LOG("connect device:%{public}s all processor end", sinkInfo.deviceName.c_str());
831     };
832     SendRequest(request, true);
833     hpaeSignalProcessThread_->ActivateThread(shared_from_this());
834     return SUCCESS;
835 }
836 
InitManager(bool isReload)837 void HpaeRendererManager::InitManager(bool isReload)
838 {
839     AUDIO_INFO_LOG("init devicename:%{public}s", sinkInfo_.deviceName.c_str());
840     HpaeNodeInfo nodeInfo;
841     nodeInfo.channels = sinkInfo_.channels;
842     nodeInfo.format = sinkInfo_.format;
843     nodeInfo.frameLen = sinkInfo_.frameLen;
844     nodeInfo.nodeId = 0;
845     nodeInfo.samplingRate = sinkInfo_.samplingRate;
846     nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT;
847     nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
848     nodeInfo.deviceClass = sinkInfo_.deviceClass;
849     nodeInfo.statusCallback = weak_from_this();
850     if (sinkInfo_.lib == "libmodule-split-stream-sink.z.so") {
851         outputCluster_ = std::make_unique<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo_);
852     } else {
853         outputCluster_ = std::make_unique<HpaeOutputCluster>(nodeInfo);
854     }
855     outputCluster_->SetTimeoutStopThd(sinkInfo_.suspendTime);
856     int32_t ret = outputCluster_->GetInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId);
857     IAudioSinkAttr attr;
858     attr.adapterName = sinkInfo_.adapterName.c_str();
859     attr.sampleRate = sinkInfo_.samplingRate;
860     attr.channel = sinkInfo_.channels;
861     attr.format = sinkInfo_.format;
862     attr.channelLayout = sinkInfo_.channelLayout;
863     attr.deviceType = sinkInfo_.deviceType;
864     attr.volume = sinkInfo_.volume;
865     attr.openMicSpeaker = sinkInfo_.openMicSpeaker;
866     attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str();
867     attr.filePath = sinkInfo_.filePath.c_str();
868     attr.aux = sinkInfo_.splitMode.c_str();
869     if (!sceneClusterMap_.count(HPAE_SCENE_EFFECT_NONE)) {
870         HpaeNodeInfo defaultNodeInfo;
871         defaultNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN;
872         defaultNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE;
873         defaultNodeInfo.format = AudioSampleFormat::INVALID_WIDTH;
874         defaultNodeInfo.channels = STEREO;
875         defaultNodeInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO;
876         defaultNodeInfo.streamType = STREAM_DEFAULT;
877         defaultNodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE;
878         defaultNodeInfo.deviceNetId = sinkInfo_.deviceNetId;
879         defaultNodeInfo.deviceClass = sinkInfo_.deviceClass;
880         defaultNodeInfo.statusCallback = weak_from_this();
881         sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] = std::make_shared<HpaeProcessCluster>(defaultNodeInfo, sinkInfo_);
882         sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE] = 1;
883     }
884 
885     ret = outputCluster_->Init(attr);
886     isInit_.store(ret == SUCCESS);
887     TriggerCallback(isReload ? RELOAD_AUDIO_SINK_RESULT :INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret);
888 }
889 
CreateOutputClusterNodeInfo(HpaeNodeInfo & nodeInfo)890 void HpaeRendererManager::CreateOutputClusterNodeInfo(HpaeNodeInfo &nodeInfo)
891 {
892     nodeInfo.channels = sinkInfo_.channels;
893     nodeInfo.format = sinkInfo_.format;
894     nodeInfo.frameLen = sinkInfo_.frameLen;
895     nodeInfo.nodeId = 0;
896     nodeInfo.samplingRate = sinkInfo_.samplingRate;
897     nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT;
898     nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
899     nodeInfo.deviceClass = sinkInfo_.deviceClass;
900     nodeInfo.statusCallback = weak_from_this();
901     return;
902 }
903 
Init(bool isReload)904 int32_t HpaeRendererManager::Init(bool isReload)
905 {
906     hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
907     auto request = [this, isReload] {
908         Trace trace("HpaeRendererManager::Init");
909         InitManager(isReload);
910     };
911     SendRequest(request, true);
912     hpaeSignalProcessThread_->ActivateThread(shared_from_this());
913     return SUCCESS;
914 }
915 
DeactivateThread()916 bool HpaeRendererManager::DeactivateThread()
917 {
918     if (hpaeSignalProcessThread_ != nullptr) {
919         hpaeSignalProcessThread_->DeactivateThread();
920         hpaeSignalProcessThread_ = nullptr;
921     }
922     hpaeNoLockQueue_.HandleRequests();
923     return true;
924 }
925 
DeInit(bool isMoveDefault)926 int32_t HpaeRendererManager::DeInit(bool isMoveDefault)
927 {
928     Trace trace("HpaeRendererManager::DeInit");
929     if (hpaeSignalProcessThread_ != nullptr) {
930         hpaeSignalProcessThread_->DeactivateThread();
931         hpaeSignalProcessThread_ = nullptr;
932     }
933     hpaeNoLockQueue_.HandleRequests();
934     if (isMoveDefault) {
935         std::string sinkName = "";
936         std::vector<uint32_t> ids;
937         AUDIO_INFO_LOG("move all sink to default sink");
938         MoveAllStreamToNewSink(sinkName, ids, MOVE_ALL);
939     }
940     if (outputCluster_ != nullptr) {
941         outputCluster_->Stop();
942         outputCluster_->DeInit();
943     }
944     for (const auto &item : sceneClusterMap_) {
945         if (item.second) {
946             item.second->SetConnectedFlag(false);
947         }
948     }
949     if (outputCluster_ != nullptr) {
950         outputCluster_->ResetAll();
951         outputCluster_ = nullptr;
952     }
953     isInit_.store(false);
954     return SUCCESS;
955 }
956 
StartRenderSink()957 int32_t HpaeRendererManager::StartRenderSink()
958 {
959     return SUCCESS;
960 }
961 
SetClientVolume(uint32_t sessionId,float volume)962 int32_t HpaeRendererManager::SetClientVolume(uint32_t sessionId, float volume)
963 {
964     return SUCCESS;
965 }
966 
SetLoudnessGain(uint32_t sessionId,float loudnessGain)967 int32_t HpaeRendererManager::SetLoudnessGain(uint32_t sessionId, float loudnessGain)
968 {
969     auto request = [this, sessionId, loudnessGain] {
970         AUDIO_INFO_LOG("set loudnessGain %{public}f to sessionId %{public}d", loudnessGain, sessionId);
971         std::shared_ptr<HpaeSinkInputNode> sinkInputNode = SafeGetMap(sinkInputNodeMap_, sessionId);
972         CHECK_AND_RETURN_LOG(sinkInputNode != nullptr,
973             "session with Id %{public}d not in sinkInputNodeMap_", sessionId);
974         sinkInputNode->SetLoudnessGain(loudnessGain);
975 
976         HpaeProcessorType processorType = GetProcessorType(sessionId);
977         std::shared_ptr<HpaeProcessCluster> processCluster = SafeGetMap(sceneClusterMap_, processorType);
978         CHECK_AND_RETURN_LOG(processCluster != nullptr,
979             "session with Id %{public}d not in sceneClusterMap_", sessionId);
980         processCluster->SetLoudnessGain(sessionId, loudnessGain);
981     };
982     SendRequest(request);
983     return SUCCESS;
984 }
985 
SetRate(uint32_t sessionId,int32_t rate)986 int32_t HpaeRendererManager::SetRate(uint32_t sessionId, int32_t rate)
987 {
988     return SUCCESS;
989 }
990 
SetAudioEffectMode(uint32_t sessionId,int32_t effectMode)991 int32_t HpaeRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode)
992 {
993     if (effectMode < EFFECT_NONE || effectMode > EFFECT_DEFAULT) {
994         return ERR_INVALID_OPERATION;
995     }
996     auto request = [this, sessionId, effectMode]() {
997         if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
998             AUDIO_WARNING_LOG("miss corresponding sinkInputNode for sessionId %{public}d", sessionId);
999             return ;
1000         }
1001         HpaeNodeInfo &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1002         if (nodeInfo.effectInfo.effectMode != static_cast<AudioEffectMode>(effectMode)) {
1003             nodeInfo.effectInfo.effectMode = static_cast<AudioEffectMode>(effectMode);
1004             size_t sinkInputNodeConnectNum = sinkInputNodeMap_[sessionId]->GetOutputPort()->GetInputNum();
1005             if (sinkInputNodeConnectNum != 0) {
1006                 AUDIO_INFO_LOG("UpdateProcessClusterConnection because effectMode to be %{public}d", effectMode);
1007                 UpdateProcessClusterConnection(sessionId, effectMode);
1008             } else {
1009                 AUDIO_INFO_LOG("no need to ProcessClusterConnection, sinkInputNodeConnectNum is %{public}zu",
1010                     sinkInputNodeConnectNum);
1011             }
1012         }
1013     };
1014     SendRequest(request);
1015     return SUCCESS;
1016 }
1017 
GetAudioEffectMode(uint32_t sessionId,int32_t & effectMode)1018 int32_t HpaeRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode)
1019 {
1020     return SUCCESS;
1021 }
1022 
SetPrivacyType(uint32_t sessionId,int32_t privacyType)1023 int32_t HpaeRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType)
1024 {
1025     return SUCCESS;
1026 }
1027 
GetPrivacyType(uint32_t sessionId,int32_t & privacyType)1028 int32_t HpaeRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType)
1029 {
1030     return SUCCESS;
1031 }
1032 
RegisterWriteCallback(uint32_t sessionId,const std::weak_ptr<IStreamCallback> & callback)1033 int32_t HpaeRendererManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr<IStreamCallback> &callback)
1034 {
1035     auto request = [this, sessionId, callback]() {
1036         AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId);
1037         if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1038             sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback);
1039         }
1040     };
1041     hpaeNoLockQueue_.PushRequest(request);
1042     return SUCCESS;
1043 }
1044 
Process()1045 void HpaeRendererManager::Process()
1046 {
1047     Trace trace("HpaeRendererManager::Process");
1048     if (outputCluster_ != nullptr && IsRunning()) {
1049         UpdateAppsUid();
1050         outputCluster_->DoProcess();
1051     }
1052 }
1053 
UpdateAppsUid()1054 void HpaeRendererManager::UpdateAppsUid()
1055 {
1056     appsUid_.clear();
1057     for (const auto &sinkInputNodePair : sinkInputNodeMap_) {
1058         if (sinkInputNodePair.second->GetState() == HPAE_SESSION_RUNNING) {
1059             appsUid_.emplace_back(sinkInputNodePair.second->GetAppUid());
1060         }
1061     }
1062     outputCluster_->UpdateAppsUid(appsUid_);
1063 }
1064 
GetWritableSize(uint32_t sessionId)1065 size_t HpaeRendererManager::GetWritableSize(uint32_t sessionId)
1066 {
1067     return SUCCESS;
1068 }
1069 
UpdateSpatializationState(uint32_t sessionId,bool spatializationEnabled,bool headTrackingEnabled)1070 int32_t HpaeRendererManager::UpdateSpatializationState(
1071     uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled)
1072 {
1073     return SUCCESS;
1074 }
1075 
UpdateMaxLength(uint32_t sessionId,uint32_t maxLength)1076 int32_t HpaeRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength)
1077 {
1078     return SUCCESS;
1079 }
1080 
SetSpeed(uint32_t sessionId,float speed)1081 void HpaeRendererManager::SetSpeed(uint32_t sessionId, float speed)
1082 {
1083     auto request = [this, sessionId, speed]() {
1084         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::SetSpeed");
1085         AUDIO_INFO_LOG("SetSpeed sessionId %{public}u, deviceName %{public}s, speed %{public}f", sessionId,
1086             sinkInfo_.deviceName.c_str(), speed);
1087         CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), "not find sessionId %{public}u", sessionId);
1088         sinkInputNodeMap_[sessionId]->SetSpeed(speed);
1089     };
1090     SendRequest(request);
1091 }
1092 
GetAllSinkInputsInfo()1093 std::vector<SinkInput> HpaeRendererManager::GetAllSinkInputsInfo()
1094 {
1095     return {};
1096 }
1097 
GetSinkInputInfo(uint32_t sessionId,HpaeSinkInputInfo & sinkInputInfo)1098 int32_t HpaeRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo)
1099 {
1100     if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
1101         return ERR_INVALID_OPERATION;
1102     }
1103     sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1104     sinkInputInfo.rendererSessionInfo = sessionNodeMap_[sessionId];
1105     return SUCCESS;
1106 }
1107 
GetSinkInfo()1108 HpaeSinkInfo HpaeRendererManager::GetSinkInfo()
1109 {
1110     return sinkInfo_;
1111 }
1112 
IsInit()1113 bool HpaeRendererManager::IsInit()
1114 {
1115     return isInit_.load();
1116 }
1117 
IsMsgProcessing()1118 bool HpaeRendererManager::IsMsgProcessing()
1119 {
1120     return !hpaeNoLockQueue_.IsFinishProcess();
1121 }
1122 
IsRunning(void)1123 bool HpaeRendererManager::IsRunning(void)
1124 {
1125     if (outputCluster_ != nullptr && hpaeSignalProcessThread_ != nullptr) {
1126         return outputCluster_->GetState() == STREAM_MANAGER_RUNNING && hpaeSignalProcessThread_->IsRunning();
1127     } else {
1128         return false;
1129     }
1130 }
1131 
SendRequest(Request && request,bool isInit)1132 void HpaeRendererManager::SendRequest(Request &&request, bool isInit)
1133 {
1134     AUDIO_DEBUG_LOG("HpaeRendererManager::isInit is %{public}s", isInit ? "true" : "false");
1135     CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeRendererManager not init");
1136     hpaeNoLockQueue_.PushRequest(std::move(request));
1137     CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_  renderer is nullptr");
1138     hpaeSignalProcessThread_->Notify();
1139 }
1140 
OnNodeStatusUpdate(uint32_t sessionId,IOperation operation)1141 void HpaeRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation)
1142 {
1143     TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation);
1144 }
1145 
OnFadeDone(uint32_t sessionId,IOperation operation)1146 void HpaeRendererManager::OnFadeDone(uint32_t sessionId, IOperation operation)
1147 {
1148     auto request = [this, sessionId, operation]() {
1149         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::OnFadeDone: " + std::to_string(operation));
1150         AUDIO_INFO_LOG("Fade done, call back at RendererManager");
1151         DisConnectInputSession(sessionId);
1152         HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPED : HPAE_SESSION_PAUSED;
1153         SetSessionState(sessionId, state);
1154         if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1155             sinkInputNodeMap_[sessionId]->SetState(state);
1156         }
1157         TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
1158     };
1159     SendRequest(request);
1160 }
1161 
RegisterReadCallback(uint32_t sessionId,const std::weak_ptr<ICapturerStreamCallback> & callback)1162 int32_t HpaeRendererManager::RegisterReadCallback(uint32_t sessionId,
1163     const std::weak_ptr<ICapturerStreamCallback> &callback)
1164 {
1165     return SUCCESS;
1166 }
1167 
OnRequestLatency(uint32_t sessionId,uint64_t & latency)1168 void HpaeRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency)
1169 {
1170     // todo: add processLatency
1171     return;
1172 }
1173 
OnNotifyQueue()1174 void HpaeRendererManager::OnNotifyQueue()
1175 {
1176     CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ is nullptr");
1177     hpaeSignalProcessThread_->Notify();
1178 }
1179 
UpdateProcessClusterConnection(uint32_t sessionId,int32_t effectMode)1180 void HpaeRendererManager::UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode)
1181 {
1182     Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::UpdateProcessClusterConnection" +
1183         "effectMode[" + std::to_string(effectMode) + "]");
1184     HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType();
1185     if (!SafeGetMap(sceneClusterMap_, sceneType)) {
1186         AUDIO_WARNING_LOG("miss corresponding process cluster for scene type %{public}d", sceneType);
1187         return;
1188     }
1189     if (isSplitProcessorType(sceneType) || sessionNodeMap_[sessionId].bypass) {
1190         AUDIO_INFO_LOG("no need to update the sceneType %{public}d", sceneType);
1191         return;
1192     }
1193 
1194     if (effectMode == EFFECT_NONE) {
1195         DisConnectInputCluster(sessionId, sceneType);
1196         ConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE);
1197     } else {
1198         DisConnectInputCluster(sessionId, HPAE_SCENE_EFFECT_NONE);
1199         ConnectProcessCluster(sessionId, sceneType);
1200     }
1201 }
1202 
GetThreadName()1203 std::string HpaeRendererManager::GetThreadName()
1204 {
1205     return sinkInfo_.deviceName;
1206 }
1207 
SetSessionFade(uint32_t sessionId,IOperation operation)1208 bool HpaeRendererManager::SetSessionFade(uint32_t sessionId, IOperation operation)
1209 {
1210     CHECK_AND_RETURN_RET_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), false,
1211         "can not get input node of session %{public}u", sessionId);
1212     HpaeProcessorType sceneType = GetProcessorType(sessionId);
1213     AUDIO_INFO_LOG("sessionId is %{public}d, sceneType is %{public}d", sessionId, sceneType);
1214     std::shared_ptr<HpaeGainNode> sessionGainNode = nullptr;
1215     if (SafeGetMap(sceneClusterMap_, sceneType)) {
1216         sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId);
1217     }
1218     if (sessionGainNode == nullptr) {
1219         AUDIO_WARNING_LOG("session %{public}d do not have gain node!", sessionId);
1220         if (operation != OPERATION_STARTED) {
1221             HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPED : HPAE_SESSION_PAUSED;
1222             SetSessionState(sessionId, state);
1223             sinkInputNodeMap_[sessionId]->SetState(state);
1224             TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
1225         }
1226         return false;
1227     }
1228     AUDIO_INFO_LOG("get gain node of session %{public}d operation %{public}d.", sessionId, operation);
1229     if (operation != OPERATION_STARTED) {
1230         HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPING : HPAE_SESSION_PAUSING;
1231         SetSessionState(sessionId, state);
1232         sinkInputNodeMap_[sessionId]->SetState(state);
1233     }
1234     sessionGainNode->SetFadeState(operation);
1235     return true;
1236 }
1237 
DumpSinkInfo()1238 int32_t HpaeRendererManager::DumpSinkInfo()
1239 {
1240     CHECK_AND_RETURN_RET_LOG(IsInit(), ERR_ILLEGAL_STATE, "HpaeRendererManager not init");
1241     auto request = [this]() {
1242         AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str());
1243         UploadDumpSinkInfo(sinkInfo_.deviceName);
1244     };
1245     SendRequest(request);
1246     return SUCCESS;
1247 }
1248 
SetOffloadPolicy(uint32_t sessionId,int32_t state)1249 int32_t HpaeRendererManager::SetOffloadPolicy(uint32_t sessionId, int32_t state)
1250 {
1251     auto request = [this, sessionId, state]() {
1252         Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::SetOffloadPolicy");
1253         AUDIO_INFO_LOG("SetOffloadPolicy sessionId %{public}u, deviceName %{public}s, state %{public}d", sessionId,
1254             sinkInfo_.deviceName.c_str(), state);
1255         if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1256             sinkInputNodeMap_[sessionId]->SetOffloadEnabled(state != OFFLOAD_DEFAULT);
1257         } else {
1258             AUDIO_ERR_LOG("not find sessionId %{public}u", sessionId);
1259         }
1260     };
1261     SendRequest(request);
1262     return SUCCESS;
1263 }
1264 
UpdateCollaborativeState(bool isCollaborationEnabled)1265 int32_t HpaeRendererManager::UpdateCollaborativeState(bool isCollaborationEnabled)
1266 {
1267     auto request = [this, isCollaborationEnabled]() {
1268         if (isCollaborationEnabled_ == isCollaborationEnabled) {
1269             AUDIO_INFO_LOG("collaboration state not changed, isCollaborationEnabled_ %{public}d",
1270                 isCollaborationEnabled_);
1271             return;
1272         }
1273         AUDIO_INFO_LOG("collaborativeState change from %{public}d to %{public}d",
1274             isCollaborationEnabled_, isCollaborationEnabled);
1275         isCollaborationEnabled_ = isCollaborationEnabled;
1276         if (isCollaborationEnabled_) {
1277             // for collaboration enabled
1278             EnableCollaboration();
1279         } else {
1280             // for collaboration disabled
1281             DisableCollaboration();
1282         }
1283     };
1284     SendRequest(request);
1285     return SUCCESS;
1286 }
1287 
HandlePriPaPower(uint32_t sessionId)1288 int32_t HpaeRendererManager::HandlePriPaPower(uint32_t sessionId)
1289 {
1290     if (!SafeGetMap(sinkInputNodeMap_, sessionId) || sinkInfo_.deviceClass != "primary") {
1291         return ERR_INVALID_OPERATION;
1292     }
1293     auto &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1294     struct VolumeValues volumes;
1295     auto audioVolume = AudioVolume::GetInstance();
1296     float curVolume = audioVolume->GetVolume(sessionId, nodeInfo.streamType, sinkInfo_.deviceClass, &volumes);
1297     auto isZeroVolume = audioVolume->IsSameVolume(0.0f, curVolume);
1298     AUDIO_INFO_LOG("session %{public}u, stream %{public}d, is zero volume %{public}d",
1299         sessionId, nodeInfo.streamType, isZeroVolume);
1300     if (!isZeroVolume) {
1301         return outputCluster_->SetPriPaPower();
1302     }
1303     return SUCCESS;
1304 }
1305 
GetDeviceHDFDumpInfo()1306 std::string HpaeRendererManager::GetDeviceHDFDumpInfo()
1307 {
1308     std::string config;
1309     TransDeviceInfoToString(sinkInfo_, config);
1310     return config;
1311 }
1312 
ConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> & coBufferNode)1313 int32_t HpaeRendererManager::ConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> &coBufferNode)
1314 {
1315     auto request = [this, coBufferNode]() {
1316         CHECK_AND_RETURN_LOG((outputCluster_ != nullptr) && (coBufferNode != nullptr),
1317             "outputCluster or coBufferNode is nullptr");
1318         if (!coBufferNode->IsOutputClusterConnected()) {
1319             outputCluster_->Connect(coBufferNode);
1320             coBufferNode->SetOutputClusterConnected(true);
1321         }
1322         if (outputCluster_->GetState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
1323             outputCluster_->Start();
1324         }
1325     };
1326     SendRequest(request);
1327     return SUCCESS;
1328 }
1329 
DisConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> & coBufferNode)1330 int32_t HpaeRendererManager::DisConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> &coBufferNode)
1331 {
1332     auto request = [this, coBufferNode]() {
1333         CHECK_AND_RETURN_LOG((outputCluster_ != nullptr) && (coBufferNode != nullptr),
1334             "outputCluster or coBufferNode is nullptr");
1335         if (coBufferNode->IsOutputClusterConnected()) {
1336             outputCluster_->DisConnect(coBufferNode);
1337             coBufferNode->SetOutputClusterConnected(false);
1338         }
1339     };
1340     SendRequest(request);
1341     return SUCCESS;
1342 }
1343 
ReConnectNodeForCollaboration(uint32_t sessionId)1344 void HpaeRendererManager::ReConnectNodeForCollaboration(uint32_t sessionId)
1345 {
1346     // todo fade out
1347     CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
1348         "sinkInputNodeMap_ not find sessionId %{public}u", sessionId);
1349     HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1350     HpaeProcessorType sceneType = GetProcessorType(sessionId);
1351     if (SafeGetMap(sceneClusterMap_, sceneType)) {
1352         DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
1353     }
1354     AUDIO_INFO_LOG("AddSingleNodeToSink sessionId %{public}u", sessionId);
1355     AddSingleNodeToSink(sinkInputNodeMap_[sessionId]);
1356 }
1357 
EnableCollaboration()1358 void HpaeRendererManager::EnableCollaboration()
1359 {
1360     if (hpaeCoBufferNode_ == nullptr) {
1361         hpaeCoBufferNode_ = std::make_shared<HpaeCoBufferNode>();
1362     }
1363 
1364     std::vector<uint32_t> sinkInputNodeMapKeys;
1365     for (auto& [key, node] : sinkInputNodeMap_) {
1366         HpaeNodeInfo nodeInfo = node->GetNodeInfo();
1367         if (nodeInfo.effectInfo.effectScene == SCENE_MUSIC || nodeInfo.effectInfo.effectScene == SCENE_MOVIE) {
1368             sinkInputNodeMapKeys.push_back(key);
1369         }
1370     }
1371 
1372     for (auto& key : sinkInputNodeMapKeys) {
1373         ReConnectNodeForCollaboration(key);
1374     }
1375 }
1376 
DisableCollaboration()1377 void HpaeRendererManager::DisableCollaboration()
1378 {
1379     std::vector<uint32_t> sinkInputNodeMapKeys;
1380     for (auto& [key, node] : sinkInputNodeMap_) {
1381         HpaeNodeInfo nodeInfo = node->GetNodeInfo();
1382         if (nodeInfo.effectInfo.effectScene == SCENE_COLLABORATIVE) {
1383             sinkInputNodeMapKeys.push_back(key);
1384         }
1385     }
1386     for (auto& key : sinkInputNodeMapKeys) {
1387         ReConnectNodeForCollaboration(key);
1388     }
1389 }
1390 
HandleSyncId(uint32_t sessionId,int32_t syncId)1391 int32_t HpaeRendererManager::HandleSyncId(uint32_t sessionId, int32_t syncId)
1392 {
1393     if (!SafeGetMap(sinkInputNodeMap_, sessionId) || sinkInfo_.deviceClass != "primary") {
1394         return ERR_INVALID_OPERATION;
1395     }
1396     return outputCluster_->SetSyncId(syncId);
1397 }
1398 }  // namespace HPAE
1399 }  // namespace AudioStandard
1400 }  // namespace OHOS