1 /*
2  * Copyright (c) 2024 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 "ProAudioStreamManager"
17 #endif
18 
19 #include "pro_audio_stream_manager.h"
20 #include <sstream>
21 #include <atomic>
22 #include "audio_service_log.h"
23 #include "audio_errors.h"
24 #include "policy_handler.h"
25 #include "pro_renderer_stream_impl.h"
26 #include "audio_engine_manager.h"
27 #include "none_mix_engine.h"
28 
29 namespace OHOS {
30 namespace AudioStandard {
31 using namespace std;
32 
ProAudioStreamManager(ManagerType type)33 ProAudioStreamManager::ProAudioStreamManager(ManagerType type)
34     : managerType_(type), playbackEngine_(std::make_unique<NoneMixEngine>())
35 {
36     AUDIO_DEBUG_LOG("ProAudioStreamManager");
37 }
38 
~ProAudioStreamManager()39 ProAudioStreamManager::~ProAudioStreamManager()
40 {
41     playbackEngine_ = nullptr;
42     AUDIO_DEBUG_LOG("~ProAudioStreamManager");
43 }
44 
CreateRender(AudioProcessConfig processConfig,std::shared_ptr<IRendererStream> & stream)45 int32_t ProAudioStreamManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr<IRendererStream> &stream)
46 {
47     AUDIO_DEBUG_LOG("Create renderer start,manager type:%{public}d", managerType_);
48     uint32_t sessionId = 0;
49     if (processConfig.originalSessionId < MIN_SESSIONID || processConfig.originalSessionId > MAX_SESSIONID) {
50         sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid);
51     } else {
52         sessionId = processConfig.originalSessionId;
53     }
54     std::shared_ptr<IRendererStream> rendererStream = CreateRendererStream(processConfig);
55     CHECK_AND_RETURN_RET_LOG(rendererStream != nullptr, ERR_DEVICE_INIT, "Failed to init rendererStream");
56     int32_t ret = CreatePlayBackEngine(rendererStream);
57     if (ret != SUCCESS) {
58         AUDIO_ERR_LOG("Create play back engine failed. ret:%{public}d", ret);
59         rendererStream = nullptr;
60         return ret;
61     }
62     rendererStream->SetStreamIndex(sessionId);
63     std::lock_guard<std::mutex> lock(streamMapMutex_);
64     rendererStreamMap_[sessionId] = rendererStream;
65     stream = rendererStream;
66     return SUCCESS;
67 }
68 
StartRender(uint32_t streamIndex)69 int32_t ProAudioStreamManager::StartRender(uint32_t streamIndex)
70 {
71     AUDIO_DEBUG_LOG("Start renderer enter");
72     std::shared_ptr<IRendererStream> currentRender;
73     std::lock_guard<std::mutex> lock(streamMapMutex_);
74     auto it = rendererStreamMap_.find(streamIndex);
75     if (it == rendererStreamMap_.end()) {
76         AUDIO_WARNING_LOG("No matching stream");
77         return SUCCESS;
78     }
79     currentRender = rendererStreamMap_[streamIndex];
80     int32_t result = currentRender->Start();
81     CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "Failed to start rendererStream");
82     if (playbackEngine_) {
83         playbackEngine_->Start();
84     }
85     return SUCCESS;
86 }
87 
StopRender(uint32_t streamIndex)88 int32_t ProAudioStreamManager::StopRender(uint32_t streamIndex)
89 {
90     AUDIO_DEBUG_LOG("Stop renderer enter");
91     std::lock_guard<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     rendererStreamMap_[streamIndex]->Stop();
98     if (playbackEngine_) {
99         playbackEngine_->Stop();
100     }
101     return SUCCESS;
102 }
103 
PauseRender(uint32_t streamIndex)104 int32_t ProAudioStreamManager::PauseRender(uint32_t streamIndex)
105 {
106     AUDIO_DEBUG_LOG("Pause renderer enter");
107     std::lock_guard<std::mutex> lock(streamMapMutex_);
108     auto it = rendererStreamMap_.find(streamIndex);
109     if (it == rendererStreamMap_.end()) {
110         AUDIO_WARNING_LOG("No matching stream");
111         return SUCCESS;
112     }
113     rendererStreamMap_[streamIndex]->Pause();
114     if (playbackEngine_) {
115         playbackEngine_->Pause();
116     }
117     return SUCCESS;
118 }
119 
ReleaseRender(uint32_t streamIndex)120 int32_t ProAudioStreamManager::ReleaseRender(uint32_t streamIndex)
121 {
122     AUDIO_DEBUG_LOG("Release renderer start");
123     std::shared_ptr<IRendererStream> currentRender;
124     {
125         std::lock_guard<std::mutex> lock(streamMapMutex_);
126         auto it = rendererStreamMap_.find(streamIndex);
127         if (it == rendererStreamMap_.end()) {
128             AUDIO_WARNING_LOG("No matching stream");
129             return SUCCESS;
130         }
131         currentRender = rendererStreamMap_[streamIndex];
132         rendererStreamMap_[streamIndex] = nullptr;
133         rendererStreamMap_.erase(streamIndex);
134         if (playbackEngine_) {
135             playbackEngine_->Stop();
136             playbackEngine_->RemoveRenderer(currentRender);
137     }
138     }
139     if (currentRender->Release() < 0) {
140         AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex);
141         return ERR_OPERATION_FAILED;
142     }
143     AUDIO_INFO_LOG("rendererStreamMap_.size() : %{public}zu", rendererStreamMap_.size());
144     if (rendererStreamMap_.size() == 0) {
145         AUDIO_INFO_LOG("Release the last stream");
146     }
147     return SUCCESS;
148 }
149 
TriggerStartIfNecessary()150 int32_t ProAudioStreamManager::TriggerStartIfNecessary()
151 {
152     if (playbackEngine_ && !playbackEngine_->IsPlaybackEngineRunning()) {
153         AUDIO_INFO_LOG("trigger re-start thread");
154         playbackEngine_->Start();
155     }
156     return SUCCESS;
157 }
158 
GetStreamCount() const159 int32_t ProAudioStreamManager::GetStreamCount() const noexcept
160 {
161     return rendererStreamMap_.size();
162 }
163 
CreatePlayBackEngine(const std::shared_ptr<IRendererStream> & stream)164 int32_t ProAudioStreamManager::CreatePlayBackEngine(const std::shared_ptr<IRendererStream> &stream)
165 {
166     int32_t ret = SUCCESS;
167     DeviceInfo deviceInfo;
168     AudioProcessConfig config = stream->GetAudioProcessConfig();
169     bool result = PolicyHandler::GetInstance().GetProcessDeviceInfo(config, true, deviceInfo);
170     CHECK_AND_RETURN_RET_LOG(result, ERR_DEVICE_INIT, "GetProcessDeviceInfo failed.");
171     CHECK_AND_RETURN_RET_LOG(playbackEngine_ != nullptr, ERR_NOT_SUPPORTED, "engine not init");
172     playbackEngine_->Init(deviceInfo, managerType_ == VOIP_PLAYBACK);
173     ret = playbackEngine_->AddRenderer(stream);
174     return ret;
175 }
176 
CreateRendererStream(AudioProcessConfig processConfig)177 std::shared_ptr<IRendererStream> ProAudioStreamManager::CreateRendererStream(AudioProcessConfig processConfig)
178 {
179     std::lock_guard<std::mutex> lock(paElementsMutex_);
180     bool isDirectStream = managerType_ == DIRECT_PLAYBACK; // direct stream (high resolution) or direct VoIP stream
181     std::shared_ptr<ProRendererStreamImpl> rendererStream =
182         std::make_shared<ProRendererStreamImpl>(processConfig, isDirectStream);
183     if (rendererStream->InitParams() != SUCCESS) {
184         AUDIO_ERR_LOG("Create rendererStream Failed");
185         return nullptr;
186     }
187     return rendererStream;
188 }
189 
CreateCapturer(AudioProcessConfig processConfig,std::shared_ptr<ICapturerStream> & stream)190 int32_t ProAudioStreamManager::CreateCapturer(AudioProcessConfig processConfig,
191                                               std::shared_ptr<ICapturerStream> &stream)
192 {
193     AUDIO_ERR_LOG("Unsupported operation: CreateCapturer");
194     return SUCCESS;
195 }
196 
ReleaseCapturer(uint32_t streamIndex)197 int32_t ProAudioStreamManager::ReleaseCapturer(uint32_t streamIndex)
198 {
199     AUDIO_ERR_LOG("Unsupported operation: ReleaseCapturer");
200     return SUCCESS;
201 }
202 } // namespace AudioStandard
203 } // namespace OHOS