• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "RendererInServer"
17 #endif
18 
19 #include "renderer_in_server.h"
20 #include <cinttypes>
21 #include "securec.h"
22 #include "audio_errors.h"
23 #include "audio_renderer_log.h"
24 #include "audio_utils.h"
25 #include "audio_service.h"
26 #include "futex_tool.h"
27 #include "i_stream_manager.h"
28 #ifdef RESSCHE_ENABLE
29 #include "res_type.h"
30 #include "res_sched_client.h"
31 #endif
32 #include "volume_tools.h"
33 #include "policy_handler.h"
34 #include "audio_enhance_chain_manager.h"
35 #include "media_monitor_manager.h"
36 #include "audio_volume.h"
37 #include "audio_dump_pcm.h"
38 #include "audio_performance_monitor.h"
39 #include "audio_volume_c.h"
40 #include "core_service_handler.h"
41 #include "audio_service_enum.h"
42 #include "i_hpae_manager.h"
43 #include "stream_dfx_manager.h"
44 #include "audio_stream_enum.h"
45 
46 namespace OHOS {
47 namespace AudioStandard {
48 namespace {
49     static const int64_t MOCK_LATENCY = 45000000; // 45000000 -> 45ms
50     static const int64_t START_MIN_COST = 80000000; // 80000000 -> 80ms
51     static const int32_t NO_FADING = 0;
52     static const int32_t DO_FADINGOUT = 1;
53     static const int32_t FADING_OUT_DONE = 2;
54     static const float FADINGOUT_BEGIN = 1.0f;
55     static const float FADINGOUT_END = 0.0f;
56     static constexpr int32_t ONE_MINUTE = 60;
57     const int32_t MEDIA_UID = 1013;
58     const float AUDIO_VOLOMUE_EPSILON = 0.0001;
59     const int32_t OFFLOAD_INNER_CAP_PREBUF = 3;
60     constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S
61     constexpr int32_t DEFAULT_SPAN_SIZE = 2;
62     constexpr size_t MSEC_PER_SEC = 1000;
63     const int32_t DUP_OFFLOAD_LEN = 7000; // 7000 -> 7000ms
64     const int32_t DUP_COMMON_LEN = 440; // 400 -> 440ms
65     const int32_t DUP_DEFAULT_LEN = 20; // 20 -> 20ms
66     const int32_t DUP_RECOVERY_AUTISHAKE_BUFFER_COUNT = 2; // 2 -> 2 frames -> 40ms
67 }
68 
RendererInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)69 RendererInServer::RendererInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
70     : processConfig_(processConfig)
71 {
72     streamListener_ = streamListener;
73     managerType_ = PLAYBACK;
74     if (processConfig_.callerUid == MEDIA_UID) {
75         isNeedFade_ = true;
76         oldAppliedVolume_ = MIN_FLOAT_VOLUME;
77     }
78     audioStreamChecker_ = std::make_shared<AudioStreamChecker>(processConfig);
79     AudioStreamMonitor::GetInstance().AddCheckForMonitor(processConfig.originalSessionId, audioStreamChecker_);
80 }
81 
~RendererInServer()82 RendererInServer::~RendererInServer()
83 {
84     if (status_ != I_STATUS_RELEASED) {
85         Release();
86     }
87     DumpFileUtil::CloseDumpFile(&dumpC2S_);
88     AudioStreamMonitor::GetInstance().DeleteCheckForMonitor(processConfig_.originalSessionId);
89 }
90 
ConfigServerBuffer()91 int32_t RendererInServer::ConfigServerBuffer()
92 {
93     if (audioServerBuffer_ != nullptr) {
94         AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
95         return SUCCESS;
96     }
97     stream_->GetSpanSizePerFrame(spanSizeInFrame_);
98     int32_t engineFlag = GetEngineFlag();
99     if (engineFlag == 1) {
100         engineTotalSizeInFrame_ = processConfig_.rendererInfo.playerType == PLAYER_TYPE_TONE_PLAYER ?
101             spanSizeInFrame_ * 4 : spanSizeInFrame_ * 2; // default 2 frames, 4 frames for toneplayer
102     } else {
103         engineTotalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE;
104     }
105     stream_->GetByteSizePerFrame(byteSizePerFrame_);
106     if (engineTotalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || engineTotalSizeInFrame_ % spanSizeInFrame_ != 0) {
107         AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
108         return ERR_INVALID_PARAM;
109     }
110 
111     size_t maxClientCbBufferInFrame = MAX_CBBUF_IN_USEC * processConfig_.streamInfo.samplingRate / AUDIO_US_PER_S;
112     bufferTotalSizeInFrame_ = engineTotalSizeInFrame_ + maxClientCbBufferInFrame;
113 
114     spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_;
115     CHECK_AND_RETURN_RET_LOG(spanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config oh audio buffer failed!");
116     AUDIO_INFO_LOG("engineTotalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu, byteSizePerFrame_:%{public}zu "
117         "spanSizeInByte_: %{public}zu, bufferTotalSizeInFrame_: %{public}zu", engineTotalSizeInFrame_,
118         spanSizeInFrame_, byteSizePerFrame_, spanSizeInByte_, bufferTotalSizeInFrame_);
119 
120     // create OHAudioBuffer in server
121     audioServerBuffer_ = OHAudioBufferBase::CreateFromLocal(bufferTotalSizeInFrame_, byteSizePerFrame_);
122     CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
123 
124     // we need to clear data buffer to avoid dirty data.
125     memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
126         audioServerBuffer_->GetDataSize());
127     int32_t ret = InitBufferStatus();
128     AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
129 
130     isBufferConfiged_ = true;
131     isInited_ = true;
132     return SUCCESS;
133 }
134 
InitBufferStatus()135 int32_t RendererInServer::InitBufferStatus()
136 {
137     if (audioServerBuffer_ == nullptr) {
138         AUDIO_ERR_LOG("InitBufferStatus failed, null buffer!");
139         return ERR_ILLEGAL_STATE;
140     }
141     return SUCCESS;
142 }
143 
GetEAC3ControlParam()144 void RendererInServer::GetEAC3ControlParam()
145 {
146     int32_t eac3TestFlag = 0;
147     GetSysPara("persist.multimedia.eac3test", eac3TestFlag);
148     if (eac3TestFlag == 1) {
149         managerType_ = EAC3_PLAYBACK;
150     }
151 }
152 
ProcessManagerType()153 void RendererInServer::ProcessManagerType()
154 {
155     if (processConfig_.rendererInfo.audioFlag == (AUDIO_OUTPUT_FLAG_HD|AUDIO_OUTPUT_FLAG_DIRECT)) {
156         Trace trace("current stream marked as high resolution");
157         managerType_ = DIRECT_PLAYBACK;
158         AUDIO_INFO_LOG("current stream marked as high resolution");
159     }
160     if (processConfig_.streamInfo.encoding == ENCODING_EAC3) {
161         managerType_ = EAC3_PLAYBACK;
162         AUDIO_INFO_LOG("current stream marked as eac3 direct stream");
163     }
164     if (processConfig_.rendererInfo.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) {
165         if (IStreamManager::GetPlaybackManager(VOIP_PLAYBACK).GetStreamCount() <= 0) {
166             AUDIO_INFO_LOG("current stream marked as VoIP direct stream");
167             managerType_ = VOIP_PLAYBACK;
168         } else {
169             AUDIO_WARNING_LOG("One VoIP direct stream has been created! Use normal mode.");
170         }
171     }
172 }
173 
Init()174 int32_t RendererInServer::Init()
175 {
176     ProcessManagerType();
177     GetEAC3ControlParam();
178     streamIndex_ = processConfig_.originalSessionId;
179     AUDIO_INFO_LOG("Stream index: %{public}u", streamIndex_);
180 
181     int32_t ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
182     if (ret != SUCCESS && (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK)) {
183         Trace trace("high resolution create failed use normal replace");
184         managerType_ = PLAYBACK;
185         ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
186         AUDIO_INFO_LOG("high resolution create failed use normal replace");
187     }
188     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
189         "Construct rendererInServer failed: %{public}d", ret);
190     bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
191     StreamVolumeParams streamVolumeParams = { streamIndex_, processConfig_.streamType,
192         processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
193         isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
194     AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
195     traceTag_ = "[" + std::to_string(streamIndex_) + "]RendererInServer"; // [100001]RendererInServer:
196     ret = ConfigServerBuffer();
197     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
198         "Construct rendererInServer failed: %{public}d", ret);
199     stream_->RegisterStatusCallback(shared_from_this());
200     stream_->RegisterWriteCallback(shared_from_this());
201 
202     // eg: /data/data/.pulse_dir/10000_100001_48000_2_1_server_in.pcm
203     AudioStreamInfo tempInfo = processConfig_.streamInfo;
204     dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
205         + "_renderer_server_in_" + std::to_string(tempInfo.samplingRate) + "_"
206         + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
207     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpC2S_);
208     playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, streamIndex_);
209 
210     return SUCCESS;
211 }
212 
CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)213 void RendererInServer::CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)
214 {
215     if (standbyEnable == lastWriteStandbyEnableStatus_) {
216         return;
217     }
218     lastWriteStandbyEnableStatus_ = standbyEnable;
219     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
220         Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
221         Media::MediaMonitor::BEHAVIOR_EVENT);
222     bean->Add("STREAMID", static_cast<int32_t>(streamIndex_));
223     bean->Add("STANDBY", standbyEnable ? 1 : 0);
224     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
225     std::unordered_map<std::string, std::string> payload;
226     payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
227     payload["sessionId"] = std::to_string(streamIndex_);
228     payload["isStandby"] = std::to_string(standbyEnable ? 1 : 0);
229     ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
230     AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
231 }
232 
OnStatusUpdate(IOperation operation)233 void RendererInServer::OnStatusUpdate(IOperation operation)
234 {
235     if (operation != OPERATION_UNDERFLOW) {
236         AUDIO_INFO_LOG("%{public}u recv operation:%{public}d standByEnable_:%{public}s", streamIndex_, operation,
237             (standByEnable_ ? "true" : "false"));
238     }
239     Trace trace(traceTag_ + " OnStatusUpdate:" + std::to_string(operation));
240     CHECK_AND_RETURN_LOG(operation != OPERATION_RELEASED, "Stream already released!");
241     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
242     CHECK_AND_RETURN_LOG((stateListener != nullptr && playerDfx_ != nullptr), "nullptr");
243     CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
244         "stream status is nullptr");
245     switch (operation) {
246         case OPERATION_STARTED:
247             HandleOperationStarted();
248             stateListener->OnOperationHandled(START_STREAM, 0);
249             break;
250         case OPERATION_PAUSED:
251             if (standByEnable_) {
252                 AUDIO_INFO_LOG("%{public}u recv stand-by paused", streamIndex_);
253                 audioServerBuffer_->GetStreamStatus()->store(STREAM_STAND_BY);
254                 CheckAndWriterRenderStreamStandbySysEvent(true);
255                 return;
256             }
257             status_ = I_STATUS_PAUSED;
258             stateListener->OnOperationHandled(PAUSE_STREAM, 0);
259             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_PAUSE_OK);
260             break;
261         case OPERATION_STOPPED:
262             status_ = I_STATUS_STOPPED;
263             stateListener->OnOperationHandled(STOP_STREAM, 0);
264             HandleOperationStopped(RENDERER_STAGE_STOP_OK);
265             break;
266         case OPERATION_FLUSHED:
267             HandleOperationFlushed();
268             stateListener->OnOperationHandled(FLUSH_STREAM, 0);
269             break;
270         case OPERATION_DRAINED:
271             // Client's StopAudioStream will call Drain first and then Stop. If server's drain times out,
272             // Stop will be completed first. After a period of time, when Drain's callback goes here,
273             // state of server should not be changed to STARTED while the client state is Stopped.
274             OnStatusUpdateExt(operation, stateListener);
275             break;
276         default:
277             OnStatusUpdateSub(operation);
278     }
279     AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
280 }
281 
GetLastAudioDuration()282 int64_t RendererInServer::GetLastAudioDuration()
283 {
284     auto ret = lastStopTime_ - lastStartTime_;
285     return ret < 0 ? -1 : ret;
286 }
287 
OnStatusUpdateExt(IOperation operation,std::shared_ptr<IStreamListener> stateListener)288 void RendererInServer::OnStatusUpdateExt(IOperation operation, std::shared_ptr<IStreamListener> stateListener)
289 {
290     if (status_ == I_STATUS_DRAINING) {
291         status_ = I_STATUS_STARTED;
292         stateListener->OnOperationHandled(DRAIN_STREAM, 0);
293     }
294     afterDrain = true;
295 }
296 
HandleOperationStarted()297 void RendererInServer::HandleOperationStarted()
298 {
299     CHECK_AND_RETURN_LOG(playerDfx_ != nullptr, "nullptr");
300     CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
301         "stream status is nullptr");
302     if (standByEnable_) {
303         standByEnable_ = false;
304         AUDIO_INFO_LOG("%{public}u recv stand-by started", streamIndex_);
305         audioServerBuffer_->GetStreamStatus()->store(STREAM_RUNNING);
306         playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
307     }
308     CheckAndWriterRenderStreamStandbySysEvent(false);
309     status_ = I_STATUS_STARTED;
310     startedTime_ = ClockTime::GetCurNano();
311 
312     lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
313         std::chrono::system_clock::now().time_since_epoch()).count();
314     lastWriteFrame_ = static_cast<int64_t>(audioServerBuffer_->GetCurReadFrame());
315     lastWriteMuteFrame_ = 0;
316 }
317 
318 // LCOV_EXCL_START
OnStatusUpdateSub(IOperation operation)319 void RendererInServer::OnStatusUpdateSub(IOperation operation)
320 {
321     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
322     CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr!");
323     int32_t engineFlag = GetEngineFlag();
324     switch (operation) {
325         case OPERATION_RELEASED:
326             stateListener->OnOperationHandled(RELEASE_STREAM, 0);
327             status_ = I_STATUS_RELEASED;
328             break;
329         case OPERATION_UNDERRUN:
330             AUDIO_INFO_LOG("Underrun: audioServerBuffer_->GetWritableDataFrames(): %{public}d",
331                 audioServerBuffer_->GetWritableDataFrames());
332             if (audioServerBuffer_->GetWritableDataFrames() ==
333                 static_cast<int32_t>(DEFAULT_SPAN_SIZE * spanSizeInFrame_)) {
334                 AUDIO_INFO_LOG("Buffer is empty");
335                 needForceWrite_ = 0;
336             } else {
337                 AUDIO_INFO_LOG("Buffer is not empty");
338                 std::unique_lock lock(writeLock_, std::try_to_lock);
339                 if (lock.owns_lock()) {
340                     WriteData();
341                 }
342             }
343             break;
344         case OPERATION_UNDERFLOW:
345             if (ClockTime::GetCurNano() - startedTime_ > START_MIN_COST) {
346                 underrunCount_++;
347                 audioServerBuffer_->SetUnderrunCount(underrunCount_);
348             }
349             StandByCheck(); // if stand by is enbaled here, stream will be paused and not recv UNDERFLOW any more.
350             break;
351         case OPERATION_SET_OFFLOAD_ENABLE:
352         case OPERATION_UNSET_OFFLOAD_ENABLE:
353             offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false;
354             if (engineFlag == 1) {
355                 ReConfigDupStreamCallback();
356             }
357             stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0);
358             break;
359         default:
360             AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
361             status_ = I_STATUS_INVALID;
362     }
363 }
364 // LCOV_EXCL_STOP
365 
ReConfigDupStreamCallback()366 void RendererInServer::ReConfigDupStreamCallback()
367 {
368     size_t dupTotalSizeInFrameTemp_ = 0;
369 
370     if (offloadEnable_ == true) {
371         dupTotalSizeInFrameTemp_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN);
372     } else {
373         dupTotalSizeInFrameTemp_ = dupSpanSizeInFrame_ * (DUP_COMMON_LEN / DUP_DEFAULT_LEN);
374     }
375     AUDIO_INFO_LOG("dupTotalSizeInFrameTemp_: %{public}zu, dupTotalSizeInFrame_: %{public}zu",
376         dupTotalSizeInFrameTemp_, dupTotalSizeInFrame_);
377     if (dupTotalSizeInFrameTemp_ == dupTotalSizeInFrame_) {
378         return;
379     }
380     dupTotalSizeInFrame_ = dupTotalSizeInFrameTemp_;
381     std::lock_guard<std::mutex> lock(dupMutex_);
382     for (auto it = innerCapIdToDupStreamCallbackMap_.begin(); it != innerCapIdToDupStreamCallbackMap_.end(); ++it) {
383         if (captureInfos_[(*it).first].dupStream != nullptr && (*it).second != nullptr &&
384             (*it).second->GetDupRingBuffer() != nullptr) {
385             (*it).second->GetDupRingBuffer()->ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false);
386         }
387     }
388 }
389 
StandByCheck()390 void RendererInServer::StandByCheck()
391 {
392     Trace trace(traceTag_ + " StandByCheck:standByCounter_:" + std::to_string(standByCounter_.load()));
393 
394     // msdp wait for uncertain time when waiting for bt reply, which may case stream change into standby mode.
395     // if client writes date when stream is changing into standby mode, it would cause drain fail problems.
396     // msdp promises to call api correctly to avoid power problems
397     if (processConfig_.rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_ULTRASONIC) {
398         return;
399     }
400     AUDIO_INFO_LOG("sessionId:%{public}u standByCounter_:%{public}u standByEnable_:%{public}s ", streamIndex_,
401         standByCounter_.load(), (standByEnable_ ? "true" : "false"));
402 
403     // direct standBy need not in here
404     if (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) {
405         return;
406     }
407 
408     if (standByEnable_) {
409         return;
410     }
411     standByCounter_++;
412     audioStreamChecker_->RecordNodataFrame();
413     if (!ShouldEnableStandBy()) {
414         return;
415     }
416 
417     // call enable stand by
418     standByEnable_ = true;
419     RecordStandbyTime(standByEnable_, true);
420     enterStandbyTime_ = ClockTime::GetCurNano();
421     // PaAdapterManager::PauseRender will hold mutex, may cause dead lock with pa_lock
422     if (managerType_ == PLAYBACK) {
423         stream_->Pause(true);
424     }
425 
426     if (playerDfx_) {
427         playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_BEGIN);
428     }
429 }
430 
ShouldEnableStandBy()431 bool RendererInServer::ShouldEnableStandBy()
432 {
433     int64_t timeCost = ClockTime::GetCurNano() - lastWriteTime_;
434     uint32_t maxStandByCounter = 50; // for 20ms, 50 * 20 = 1000ms
435     int64_t timeLimit = 1000000000; // 1s
436     if (offloadEnable_) {
437         maxStandByCounter = 400; // for 20ms, 50 * 400 = 8000ms
438         timeLimit = 8 * AUDIO_NS_PER_SECOND; // for 20ms 8s
439     }
440     if (standByCounter_ >= maxStandByCounter && timeCost >= timeLimit) {
441         AUDIO_INFO_LOG("sessionId:%{public}u reach the limit of stand by: %{public}u time:%{public}" PRId64"ns",
442             streamIndex_, standByCounter_.load(), timeCost);
443         return true;
444     }
445     return false;
446 }
447 
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)448 int32_t RendererInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
449 {
450     Trace trace("RendererInServer::GetStandbyStatus:" + std::to_string(streamIndex_) + (standByEnable_ ? " Enabled" :
451         "Disabled"));
452     isStandby = standByEnable_;
453     if (isStandby) {
454         enterStandbyTime = enterStandbyTime_;
455     } else {
456         enterStandbyTime = 0;
457     }
458     return SUCCESS;
459 }
460 
HandleOperationFlushed()461 void RendererInServer::HandleOperationFlushed()
462 {
463     switch (status_) {
464         case I_STATUS_FLUSHING_WHEN_STARTED:
465             status_ = I_STATUS_STARTED;
466             break;
467         case I_STATUS_FLUSHING_WHEN_PAUSED:
468             status_ = I_STATUS_PAUSED;
469             break;
470         case I_STATUS_FLUSHING_WHEN_STOPPED:
471             status_ = I_STATUS_STOPPED;
472             break;
473         default:
474             AUDIO_WARNING_LOG("Invalid status before flusing");
475     }
476 }
477 
HandleOperationStopped(RendererStage stage)478 void RendererInServer::HandleOperationStopped(RendererStage stage)
479 {
480     CHECK_AND_RETURN_LOG(audioServerBuffer_ != nullptr && playerDfx_ != nullptr, "nullptr");
481     lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
482         std::chrono::system_clock::now().time_since_epoch()).count();
483     lastWriteFrame_ = static_cast<int64_t>(audioServerBuffer_->GetCurReadFrame()) - lastWriteFrame_;
484     playerDfx_->WriteDfxStopMsg(streamIndex_, stage,
485         {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
486 }
487 
DequeueBuffer(size_t length)488 BufferDesc RendererInServer::DequeueBuffer(size_t length)
489 {
490     return stream_->DequeueBuffer(length);
491 }
492 
DoFadingOut(RingBufferWrapper & bufferDesc)493 void RendererInServer::DoFadingOut(RingBufferWrapper& bufferDesc)
494 {
495     std::lock_guard<std::mutex> lock(fadeoutLock_);
496     if (fadeoutFlag_ == DO_FADINGOUT) {
497         AUDIO_INFO_LOG("enter. format:%{public}u", processConfig_.streamInfo.format);
498         AudioChannel channel = processConfig_.streamInfo.channels;
499         ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, FADINGOUT_BEGIN, FADINGOUT_END);
500         int32_t ret = VolumeTools::Process(bufferDesc, processConfig_.streamInfo.format, mapVols);
501         if (ret != SUCCESS) {
502             AUDIO_WARNING_LOG("VolumeTools::Process failed: %{public}d", ret);
503         }
504         fadeoutFlag_ = FADING_OUT_DONE;
505         AUDIO_INFO_LOG("fadeoutFlag_ = FADING_OUT_DONE");
506     }
507 }
508 
IsInvalidBuffer(uint8_t * buffer,size_t bufferSize)509 bool RendererInServer::IsInvalidBuffer(uint8_t *buffer, size_t bufferSize)
510 {
511     bool isInvalid = false;
512     uint8_t ui8Data = 0;
513     int16_t i16Data = 0;
514     switch (processConfig_.streamInfo.format) {
515         case SAMPLE_U8:
516             CHECK_AND_RETURN_RET_LOG(bufferSize > 0, false, "buffer size is too small");
517             ui8Data = *buffer;
518             isInvalid = ui8Data == 0;
519             break;
520         case SAMPLE_S16LE:
521             CHECK_AND_RETURN_RET_LOG(bufferSize > 1, false, "buffer size is too small");
522             i16Data = *(reinterpret_cast<const int16_t*>(buffer));
523             isInvalid = i16Data == 0;
524             break;
525         default:
526             break;
527     }
528     return isInvalid;
529 }
530 
WriteMuteDataSysEvent(BufferDesc & bufferDesc)531 void RendererInServer::WriteMuteDataSysEvent(BufferDesc &bufferDesc)
532 {
533     int64_t muteFrameCnt = 0;
534     VolumeTools::CalcMuteFrame(bufferDesc, processConfig_.streamInfo, traceTag_, volumeDataCount_, muteFrameCnt);
535     lastWriteMuteFrame_ += muteFrameCnt;
536     if (volumeDataCount_ < 0) {
537         audioStreamChecker_->RecordMuteFrame();
538     }
539     if (silentModeAndMixWithOthers_) {
540         return;
541     }
542     if (IsInvalidBuffer(bufferDesc.buffer, bufferDesc.bufLength)) {
543         if (startMuteTime_ == 0) {
544             startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
545         }
546         std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
547         if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isInSilentState_) {
548             isInSilentState_ = true;
549             AUDIO_WARNING_LOG("write invalid data for some time in server");
550 
551             std::unordered_map<std::string, std::string> payload;
552             payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
553             payload["sessionId"] = std::to_string(streamIndex_);
554             payload["isSilent"] = std::to_string(true);
555             ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
556         }
557     } else {
558         if (startMuteTime_ != 0) {
559             startMuteTime_ = 0;
560         }
561         if (isInSilentState_) {
562             AUDIO_WARNING_LOG("begin write valid data in server");
563             isInSilentState_ = false;
564 
565             std::unordered_map<std::string, std::string> payload;
566             payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
567             payload["sessionId"] = std::to_string(streamIndex_);
568             payload["isSilent"] = std::to_string(false);
569             ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
570         }
571     }
572 
573     if ((!latestForWorkgroupInited_) || (latestForWorkgroup_.isInSilentState != isInSilentState_)) {
574         AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
575     }
576 }
577 
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)578 void RendererInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
579 {
580 #ifdef RESSCHE_ENABLE
581     AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
582     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
583 #endif
584 }
585 
VolumeHandle(BufferDesc & desc)586 void RendererInServer::VolumeHandle(BufferDesc &desc)
587 {
588     // volume process in server
589     if (audioServerBuffer_ == nullptr) {
590         AUDIO_WARNING_LOG("buffer in not inited");
591         return;
592     }
593     float applyVolume = 0.0f;
594     if (muteFlag_) {
595         applyVolume = 0.0f;
596     } else {
597         applyVolume = audioServerBuffer_->GetStreamVolume();
598     }
599     float duckVolume = audioServerBuffer_->GetDuckFactor();
600     float muteVolume = audioServerBuffer_->GetMuteFactor();
601     if (!IsVolumeSame(MAX_FLOAT_VOLUME, lowPowerVolume_, AUDIO_VOLOMUE_EPSILON)) {
602         applyVolume *= lowPowerVolume_;
603     }
604     if (!IsVolumeSame(MAX_FLOAT_VOLUME, duckVolume, AUDIO_VOLOMUE_EPSILON)) {
605         applyVolume *= duckVolume;
606     }
607     if (!IsVolumeSame(MAX_FLOAT_VOLUME, muteVolume, AUDIO_VOLOMUE_EPSILON)) {
608         applyVolume *= muteVolume;
609     }
610 
611     if (silentModeAndMixWithOthers_) {
612         applyVolume = 0.0f;
613     }
614 
615     //in plan: put system volume handle here
616     if (!IsVolumeSame(MAX_FLOAT_VOLUME, applyVolume, AUDIO_VOLOMUE_EPSILON) ||
617         !IsVolumeSame(oldAppliedVolume_, applyVolume, AUDIO_VOLOMUE_EPSILON)) {
618         Trace traceVol("RendererInServer::VolumeTools::Process " + std::to_string(oldAppliedVolume_) + "~" +
619             std::to_string(applyVolume));
620         AudioChannel channel = processConfig_.streamInfo.channels;
621         ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, oldAppliedVolume_, applyVolume);
622         int32_t volRet = VolumeTools::Process(desc, processConfig_.streamInfo.format, mapVols);
623         oldAppliedVolume_ = applyVolume;
624         if (volRet != SUCCESS) {
625             AUDIO_WARNING_LOG("VolumeTools::Process error: %{public}d", volRet);
626         }
627     }
628 }
629 
PrepareOutputBuffer(const RingBufferWrapper & ringBufferDesc)630 BufferDesc RendererInServer::PrepareOutputBuffer(const RingBufferWrapper& ringBufferDesc)
631 {
632     BufferDesc bufferDesc;
633     if (ringBufferDesc.basicBufferDescs[0].bufLength >= ringBufferDesc.dataLength) {
634         bufferDesc.buffer = ringBufferDesc.basicBufferDescs[0].buffer;
635         bufferDesc.bufLength = ringBufferDesc.dataLength;
636         bufferDesc.dataLength = ringBufferDesc.dataLength;
637     } else {
638         rendererTmpBuffer_.resize(ringBufferDesc.dataLength);
639         RingBufferWrapper tmpWrapper;
640         tmpWrapper.dataLength = ringBufferDesc.dataLength;
641         tmpWrapper.basicBufferDescs[0].buffer = rendererTmpBuffer_.data();
642         tmpWrapper.basicBufferDescs[0].bufLength = ringBufferDesc.dataLength;
643         tmpWrapper.CopyInputBufferValueToCurBuffer(ringBufferDesc);
644 
645         bufferDesc.buffer = rendererTmpBuffer_.data();
646         bufferDesc.bufLength = ringBufferDesc.dataLength;
647         bufferDesc.dataLength = ringBufferDesc.dataLength;
648     }
649     return bufferDesc;
650 }
651 
WriteData()652 int32_t RendererInServer::WriteData()
653 {
654     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
655     uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
656     Trace trace1(traceTag_ + " WriteData"); // RendererInServer::sessionid:100001 WriteData
657     if (currentReadFrame >= currentWriteFrame) {
658         Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
659         if (!offloadEnable_) {
660             CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
661                 "invalid write and read position.");
662             uint64_t dataSize = currentWriteFrame - currentReadFrame;
663             AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
664                 streamIndex_, dataSize);
665         }
666         return ERR_OPERATION_FAILED;
667     }
668 
669     RingBufferWrapper ringBufferDesc; // will be changed in GetReadbuffer
670     if (audioServerBuffer_->GetAllReadableBufferFromPosFrame(currentReadFrame, ringBufferDesc) == SUCCESS) {
671         ringBufferDesc.dataLength = std::min(ringBufferDesc.dataLength, spanSizeInByte_);
672         if (ringBufferDesc.dataLength == 0) {
673             AUDIO_ERR_LOG("not enough data!");
674             return ERR_INVALID_PARAM;
675         }
676         uint64_t durationMs = ((byteSizePerFrame_ * processConfig_.streamInfo.samplingRate) == 0) ? 0
677             : ((MSEC_PER_SEC * processConfig_.rendererInfo.expectedPlaybackDurationBytes) /
678             (byteSizePerFrame_ * processConfig_.streamInfo.samplingRate));
679         if (processConfig_.streamType != STREAM_ULTRASONIC && (GetFadeStrategy(durationMs) == FADE_STRATEGY_DEFAULT)) {
680             if (currentReadFrame + spanSizeInFrame_ >= currentWriteFrame) {
681                 DoFadingOut(ringBufferDesc);
682             }
683         }
684 
685         BufferDesc bufferDesc = PrepareOutputBuffer(ringBufferDesc);
686         stream_->EnqueueBuffer(bufferDesc);
687         if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
688             DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
689             AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
690                 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
691         }
692 
693         OtherStreamEnqueue(bufferDesc);
694 
695         WriteMuteDataSysEvent(bufferDesc);
696         ringBufferDesc.SetBuffersValueWithSpecifyDataLen(0); // clear is needed for reuse.
697         // Client may write the buffer immediately after SetCurReadFrame, so put memset_s before it!
698         uint64_t nextReadFrame = currentReadFrame + (ringBufferDesc.dataLength / byteSizePerFrame_);
699         audioServerBuffer_->SetCurReadFrame(nextReadFrame);
700     }
701     standByCounter_ = 0;
702     lastWriteTime_ = ClockTime::GetCurNano();
703     return SUCCESS;
704 }
705 
GetAvailableSize(size_t & length)706 int32_t RendererInServer::GetAvailableSize(size_t &length)
707 {
708     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
709     uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
710     if (currentWriteFrame < currentReadFrame) {
711         return ERROR;
712     }
713 
714     length = static_cast<size_t>((currentWriteFrame - currentReadFrame) * byteSizePerFrame_);
715     return SUCCESS;
716 }
717 
CopyDataToInputBuffer(int8_t * inputData,size_t requestDataLen,const RingBufferWrapper & ringBufferDesc)718 void RendererInServer::CopyDataToInputBuffer(int8_t* inputData, size_t requestDataLen,
719     const RingBufferWrapper& ringBufferDesc)
720 {
721     RingBufferWrapper wrapperInputData = {
722         .basicBufferDescs = {{
723             {reinterpret_cast<uint8_t*>(inputData), requestDataLen},
724             {}
725         }},
726         .dataLength = requestDataLen
727     };
728 
729     CHECK_AND_RETURN_LOG(wrapperInputData.CopyInputBufferValueToCurBuffer(ringBufferDesc) == 0,
730         "memcpy error");
731 }
732 
ProcessFadeOutIfNeeded(RingBufferWrapper & ringBufferDesc,uint64_t currentReadFrame,uint64_t currentWriteFrame,size_t requestDataInFrame)733 void RendererInServer::ProcessFadeOutIfNeeded(RingBufferWrapper& ringBufferDesc,
734     uint64_t currentReadFrame, uint64_t currentWriteFrame,
735     size_t requestDataInFrame)
736 {
737     if (processConfig_.streamType != STREAM_ULTRASONIC &&
738         currentReadFrame + requestDataInFrame == currentWriteFrame) {
739         DoFadingOut(ringBufferDesc);
740     }
741 }
742 
OnWriteData(int8_t * inputData,size_t requestDataLen)743 int32_t RendererInServer::OnWriteData(int8_t *inputData, size_t requestDataLen)
744 {
745     size_t requestDataInFrame = requestDataLen / byteSizePerFrame_;
746     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
747     uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
748     Trace trace1(traceTag_ + " OnWriteData"); // RendererInServer::sessionid:100001 WriteData
749     if (requestDataLen == 0 || currentReadFrame + requestDataInFrame > currentWriteFrame) {
750         Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
751         if (!offloadEnable_) {
752             CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
753                 "invalid write and read position.");
754             uint64_t dataSize = currentWriteFrame - currentReadFrame;
755             AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
756                 streamIndex_, dataSize);
757         }
758         return ERR_OPERATION_FAILED;
759     }
760 
761     RingBufferWrapper ringBufferDesc; // will be changed in GetReadbuffer
762     if (audioServerBuffer_->GetAllReadableBufferFromPosFrame(currentReadFrame, ringBufferDesc) == SUCCESS) {
763         if (ringBufferDesc.dataLength < requestDataLen) {
764             AUDIO_ERR_LOG("data not enouth");
765             return ERR_INVALID_PARAM;
766         }
767         ringBufferDesc.dataLength = requestDataLen;
768         ProcessFadeOutIfNeeded(ringBufferDesc, currentReadFrame, currentWriteFrame, requestDataInFrame);
769 
770         CopyDataToInputBuffer(inputData, requestDataLen, ringBufferDesc);
771 
772         BufferDesc bufferDesc = {
773             .buffer = reinterpret_cast<uint8_t*>(inputData),
774             .bufLength = requestDataLen,
775             .dataLength = requestDataLen
776         };
777 
778         if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
779             DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
780             AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
781                 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
782         }
783 
784         OtherStreamEnqueue(bufferDesc);
785         audioStreamChecker_->RecordNormalFrame();
786         WriteMuteDataSysEvent(bufferDesc);
787         ringBufferDesc.SetBuffersValueWithSpecifyDataLen(0); // clear is needed for reuse.
788         uint64_t nextReadFrame = currentReadFrame + requestDataInFrame;
789         audioServerBuffer_->SetCurReadFrame(nextReadFrame);
790     } else {
791         Trace trace3("RendererInServer::WriteData GetReadbuffer failed");
792     }
793     standByCounter_ = 0;
794     lastWriteTime_ = ClockTime::GetCurNano();
795     return SUCCESS;
796 }
797 
OtherStreamEnqueue(const BufferDesc & bufferDesc)798 void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc)
799 {
800     {
801         // for inner capture
802         std::lock_guard<std::mutex> captureLock(dupMutex_);
803         for (auto &capInfo : captureInfos_) {
804             InnerCaptureOtherStream(bufferDesc, capInfo.second, capInfo.first);
805         }
806     }
807     // for dual tone
808     if (isDualToneEnabled_) {
809         Trace traceDup("RendererInServer::WriteData DualToneSteam write");
810         std::lock_guard<std::mutex> lock(dualToneMutex_);
811         if (dualToneStream_ != nullptr) {
812             dualToneStream_->EnqueueBuffer(bufferDesc); // what if enqueue fail?
813         }
814     }
815 }
816 
InnerCaptureEnqueueBuffer(const BufferDesc & bufferDesc,CaptureInfo & captureInfo,int32_t innerCapId)817 void RendererInServer::InnerCaptureEnqueueBuffer(const BufferDesc &bufferDesc, CaptureInfo &captureInfo,
818     int32_t innerCapId)
819 {
820     int32_t engineFlag = GetEngineFlag();
821     if (renderEmptyCountForInnerCap_ > 0) {
822         size_t emptyBufferSize = static_cast<size_t>(renderEmptyCountForInnerCap_) * spanSizeInByte_;
823         auto buffer = std::make_unique<uint8_t []>(emptyBufferSize);
824         BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize};
825         memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength);
826         if (engineFlag == 1) {
827             WriteDupBufferInner(emptyBufferDesc, innerCapId);
828         } else {
829             captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc);
830         }
831         renderEmptyCountForInnerCap_ = 0;
832     }
833     if (engineFlag == 1) {
834         AUDIO_INFO_LOG("OtherStreamEnqueue running");
835         WriteDupBufferInner(bufferDesc, innerCapId);
836     } else {
837         captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail?
838     }
839 }
840 
InnerCaptureOtherStream(const BufferDesc & bufferDesc,CaptureInfo & captureInfo,int32_t innerCapId)841 void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo,
842     int32_t innerCapId)
843 {
844     if (captureInfo.isInnerCapEnabled) {
845         Trace traceDup("RendererInServer::WriteData DupSteam write");
846         if (captureInfo.dupStream != nullptr) {
847             InnerCaptureEnqueueBuffer(bufferDesc, captureInfo, innerCapId);
848         }
849     }
850 }
851 
WriteEmptyData()852 void RendererInServer::WriteEmptyData()
853 {
854     Trace trace("RendererInServer::WriteEmptyData");
855     AUDIO_WARNING_LOG("Underrun, write empty data");
856     BufferDesc bufferDesc = stream_->DequeueBuffer(spanSizeInByte_);
857     memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
858     stream_->EnqueueBuffer(bufferDesc);
859     return;
860 }
861 
OnWriteData(size_t length)862 int32_t RendererInServer::OnWriteData(size_t length)
863 {
864     Trace trace("RendererInServer::OnWriteData length " + std::to_string(length));
865     bool mayNeedForceWrite = false;
866     std::unique_lock lock(writeLock_, std::defer_lock);
867     if (lock.try_lock()) {
868         // length unit is bytes, using spanSizeInByte_
869         if (spanSizeInByte_ <= 0) {
870             return ERR_WRITE_FAILED;
871         }
872         for (size_t i = 0; i < length / spanSizeInByte_; i++) {
873             mayNeedForceWrite = WriteData() != SUCCESS || mayNeedForceWrite;
874         }
875         lock.unlock();
876     } else {
877         mayNeedForceWrite = true;
878     }
879 
880     size_t maxEmptyCount = 1;
881     size_t writableSize = stream_->GetWritableSize();
882     if (mayNeedForceWrite && writableSize >= spanSizeInByte_ * maxEmptyCount) {
883         AUDIO_DEBUG_LOG("Server need force write to recycle callback");
884         needForceWrite_ =
885             writableSize / spanSizeInByte_ > 3 ? 0 : 3 - writableSize / spanSizeInByte_; // 3 is maxlength - 1
886     }
887 
888     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
889     audioServerBuffer_->SetHandleInfo(currentReadFrame, ClockTime::GetCurNano() + MOCK_LATENCY);
890 
891     if (mayNeedForceWrite) {
892         return ERR_RENDERER_IN_SERVER_UNDERRUN;
893     }
894 
895     return SUCCESS;
896 }
897 
898 // Call WriteData will hold mainloop lock in EnqueueBuffer, we should not lock a mutex in WriteData while OnWriteData is
899 // called with mainloop locking.
UpdateWriteIndex()900 int32_t RendererInServer::UpdateWriteIndex()
901 {
902     Trace trace("RendererInServer::UpdateWriteIndex needForceWrite" + std::to_string(needForceWrite_));
903     if (managerType_ != PLAYBACK) {
904         IStreamManager::GetPlaybackManager(managerType_).TriggerStartIfNecessary();
905     }
906     std::unique_lock lock(writeLock_, std::defer_lock);
907     if (needForceWrite_ < 3 && stream_->GetWritableSize() >= spanSizeInByte_) { // 3 is maxlength - 1
908         if (lock.try_lock()) {
909             AUDIO_DEBUG_LOG("Start force write data");
910             int32_t ret = WriteData();
911             if (ret == SUCCESS) {
912                 needForceWrite_++;
913             }
914             lock.unlock();
915         }
916     }
917 
918     int32_t engineFlag = GetEngineFlag();
919     if (engineFlag != 1) {
920         if (afterDrain == true) {
921             if (lock.try_lock()) {
922                 afterDrain = false;
923                 AUDIO_DEBUG_LOG("After drain, start write data");
924                 WriteData();
925                 lock.unlock();
926             }
927         }
928     }
929     return SUCCESS;
930 }
931 
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)932 int32_t RendererInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
933 {
934     AUDIO_ERR_LOG("Not support");
935     return SUCCESS;
936 }
937 
ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> & buffer,uint32_t & spanSizeInFrame,uint64_t & engineTotalSizeInFrame)938 int32_t RendererInServer::ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> &buffer,
939     uint32_t &spanSizeInFrame, uint64_t &engineTotalSizeInFrame)
940 {
941     buffer = audioServerBuffer_;
942     spanSizeInFrame = spanSizeInFrame_;
943     engineTotalSizeInFrame = engineTotalSizeInFrame_;
944     return SUCCESS;
945 }
946 
GetSessionId(uint32_t & sessionId)947 int32_t RendererInServer::GetSessionId(uint32_t &sessionId)
948 {
949     CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
950     sessionId = streamIndex_;
951     CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
952         sessionId);
953 
954     return SUCCESS;
955 }
956 
Start()957 int32_t RendererInServer::Start()
958 {
959     AudioXCollie audioXCollie(
960         "RendererInServer::Start", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
961             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
962     int32_t ret = StartInner();
963     RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
964     if (playerDfx_) {
965         playerDfx_->WriteDfxStartMsg(streamIndex_, stage, sourceDuration_, processConfig_);
966     }
967     if (ret == SUCCESS) {
968         StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, true);
969     }
970     return ret;
971 }
972 
StartInnerDuringStandby()973 int32_t RendererInServer::StartInnerDuringStandby()
974 {
975     int32_t ret = 0;
976     AUDIO_INFO_LOG("sessionId: %{public}u call to exit stand by!", streamIndex_);
977     CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr, ERR_OPERATION_FAILED, "null stream");
978     standByCounter_ = 0;
979     startedTime_ = ClockTime::GetCurNano();
980     audioServerBuffer_->GetStreamStatus()->store(STREAM_STARTING);
981     ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_START);
982     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy start client failed, reason: %{public}d", ret);
983     ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
984         IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
985     RecordStandbyTime(true, false);
986     return ret;
987 }
988 
StartInner()989 int32_t RendererInServer::StartInner()
990 {
991     AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_);
992     int32_t ret = 0;
993     if (standByEnable_) {
994         return StartInnerDuringStandby();
995     } else {
996         audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_START, false);
997     }
998     needForceWrite_ = 0;
999     std::unique_lock<std::mutex> lock(statusLock_);
1000     if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
1001         AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1002         return ERR_ILLEGAL_STATE;
1003     }
1004     status_ = I_STATUS_STARTING;
1005     std::unique_lock<std::mutex> fadeLock(fadeoutLock_);
1006     AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
1007     fadeoutFlag_ = NO_FADING;
1008     fadeLock.unlock();
1009     ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_START);
1010     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy start client failed, reason: %{public}d", ret);
1011     ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1012         IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
1013     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
1014 
1015     startedTime_ = ClockTime::GetCurNano();
1016     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
1017     int64_t tempTime = ClockTime::GetCurNano() + MOCK_LATENCY;
1018     audioServerBuffer_->SetHandleInfo(currentReadFrame, tempTime);
1019     AUDIO_INFO_LOG("Server update position %{public}" PRIu64" time%{public} " PRId64".", currentReadFrame, tempTime);
1020     resetTime_ = true;
1021 
1022     std::unique_lock<std::mutex> dupLock(dupMutex_);
1023     for (auto &capInfo : captureInfos_) {
1024         if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1025             capInfo.second.dupStream->Start();
1026         }
1027     }
1028     dupLock.unlock();
1029     enterStandbyTime_ = 0;
1030 
1031     dualToneStreamInStart();
1032     AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(streamIndex_, processConfig_.appInfo.appTokenId);
1033     return SUCCESS;
1034 }
1035 
dualToneStreamInStart()1036 void RendererInServer::dualToneStreamInStart()
1037 {
1038     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1039         //Joint judgment ensures that there is a double ring and there is a stream to enter.
1040         stream_->GetAudioEffectMode(effectModeWhenDual_);
1041         stream_->SetAudioEffectMode(EFFECT_NONE);
1042         std::lock_guard<std::mutex> lock(dualToneMutex_);
1043         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1044         if (dualToneStream_ != nullptr) {
1045             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1046             //modified elsewhere, it was decided again after the lock was awarded.
1047             dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1048             dualToneStream_->Start();
1049         }
1050     }
1051 }
1052 
RecordStandbyTime(bool isStandby,bool isStandbyStart)1053 void RendererInServer::RecordStandbyTime(bool isStandby, bool isStandbyStart)
1054 {
1055     if (!isStandby) {
1056         AUDIO_DEBUG_LOG("Not in standby, no need record time");
1057         return;
1058     }
1059     audioStreamChecker_->RecordStandbyTime(isStandbyStart);
1060 }
1061 
Pause()1062 int32_t RendererInServer::Pause()
1063 {
1064     AUDIO_INFO_LOG("Pause.");
1065     AudioXCollie audioXCollie("RendererInServer::Pause", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1066             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1067     std::unique_lock<std::mutex> lock(statusLock_);
1068     CHECK_AND_RETURN_RET_LOG(status_ == I_STATUS_STARTED, ERR_ILLEGAL_STATE,
1069         "RendererInServer::Pause failed, Illegal state: %{public}u", status_.load());
1070     status_ = I_STATUS_PAUSING;
1071     bool isStandbyTmp = false;
1072     if (standByEnable_) {
1073         AUDIO_INFO_LOG("sessionId: %{public}u call Pause while stand by", streamIndex_);
1074         CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
1075             ERR_OPERATION_FAILED, "stream status is nullptr");
1076         standByEnable_ = false;
1077         enterStandbyTime_ = 0;
1078         audioServerBuffer_->GetStreamStatus()->store(STREAM_PAUSED);
1079         if (playerDfx_) {
1080             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
1081         }
1082         isStandbyTmp = true;
1083     }
1084     standByCounter_ = 0;
1085     GetEAC3ControlParam();
1086     int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1087         IStreamManager::GetPlaybackManager(managerType_).PauseRender(streamIndex_) : stream_->Pause();
1088     {
1089         std::lock_guard<std::mutex> lock(dupMutex_);
1090         for (auto &capInfo : captureInfos_) {
1091             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1092                 capInfo.second.dupStream->Pause();
1093             }
1094         }
1095     }
1096     pausedTime_ = ClockTime::GetCurNano();
1097     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1098         //Joint judgment ensures that there is a double ring and there is a stream to enter.
1099         stream_->SetAudioEffectMode(effectModeWhenDual_);
1100         std::lock_guard<std::mutex> lock(dualToneMutex_);
1101         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1102         if (dualToneStream_ != nullptr) {
1103             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1104             //modified elsewhere, it was decided again after the lock was awarded.
1105             dualToneStream_->Pause();
1106         }
1107     }
1108     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
1109     CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_PAUSE);
1110     audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_PAUSE, isStandbyTmp);
1111     StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1112     AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(streamIndex_);
1113     return SUCCESS;
1114 }
1115 
FlushOhAudioBuffer()1116 int32_t RendererInServer::FlushOhAudioBuffer()
1117 {
1118     std::lock_guard writeLock(writeLock_);
1119     // Flush buffer of audio server
1120     uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
1121     uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
1122     if (readFrame >= writeFrame) {
1123         AUDIO_ERR_LOG("readFrame: %{public}" PRIu64 " writeFrame: %{public}" PRIu64 "", readFrame, writeFrame);
1124         return ERR_ILLEGAL_STATE;
1125     }
1126     RingBufferWrapper buffer;
1127     int32_t readResult = audioServerBuffer_->GetAllReadableBuffer(buffer);
1128     if (readResult != 0) {
1129         return ERR_OPERATION_FAILED;
1130     }
1131     buffer.SetBuffersValueWithSpecifyDataLen(0);
1132     AUDIO_INFO_LOG("On flush, read frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
1133         "writeFrame: %{public}" PRIu64 "", readFrame, spanSizeInFrame_, writeFrame);
1134     audioServerBuffer_->SetCurReadFrame(writeFrame);
1135 
1136     return SUCCESS;
1137 }
1138 
Flush()1139 int32_t RendererInServer::Flush()
1140 {
1141     AUDIO_PRERELEASE_LOGI("Flush.");
1142     AudioXCollie audioXCollie(
1143         "RendererInServer::Flush", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1144             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1145     Trace trace(traceTag_ + " Flush");
1146     std::unique_lock<std::mutex> lock(statusLock_);
1147     if (status_ == I_STATUS_STARTED) {
1148         status_ = I_STATUS_FLUSHING_WHEN_STARTED;
1149     } else if (status_ == I_STATUS_PAUSED) {
1150         status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
1151     } else if (status_ == I_STATUS_STOPPED) {
1152         status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
1153     } else {
1154         AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1155         return ERR_ILLEGAL_STATE;
1156     }
1157 
1158     FlushOhAudioBuffer();
1159 
1160     flushedTime_ = ClockTime::GetCurNano();
1161     int ret = stream_->Flush();
1162     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
1163     {
1164         std::lock_guard<std::mutex> lock(dupMutex_);
1165         for (auto &capInfo : captureInfos_) {
1166             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1167                 capInfo.second.dupStream->Flush();
1168             }
1169         }
1170     }
1171     if (isDualToneEnabled_) {
1172         std::lock_guard<std::mutex> lock(dualToneMutex_);
1173         if (dualToneStream_ != nullptr) {
1174             dualToneStream_->Flush();
1175         }
1176     }
1177     return SUCCESS;
1178 }
1179 
DrainAudioBuffer()1180 int32_t RendererInServer::DrainAudioBuffer()
1181 {
1182     return SUCCESS;
1183 }
1184 
Drain(bool stopFlag)1185 int32_t RendererInServer::Drain(bool stopFlag)
1186 {
1187     AudioXCollie audioXCollie(
1188         "RendererInServer::Drain", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1189             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1190     {
1191         std::unique_lock<std::mutex> lock(statusLock_);
1192         if (status_ != I_STATUS_STARTED) {
1193             AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1194             return ERR_ILLEGAL_STATE;
1195         }
1196         status_ = I_STATUS_DRAINING;
1197     }
1198     AUDIO_INFO_LOG("Start drain. stopFlag:%{public}d", stopFlag);
1199     if (stopFlag) {
1200         std::lock_guard<std::mutex> lock(fadeoutLock_);
1201         AUDIO_INFO_LOG("fadeoutFlag_ = DO_FADINGOUT");
1202         fadeoutFlag_ = DO_FADINGOUT;
1203     }
1204     DrainAudioBuffer();
1205     drainedTime_ = ClockTime::GetCurNano();
1206     AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(streamIndex_, processConfig_.appInfo.appTokenId);
1207     int ret = stream_->Drain(stopFlag);
1208     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Drain stream failed, reason: %{public}d", ret);
1209     {
1210         std::lock_guard<std::mutex> lock(dupMutex_);
1211         for (auto &capInfo : captureInfos_) {
1212             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1213                 capInfo.second.dupStream->Drain(stopFlag);
1214             }
1215         }
1216     }
1217     if (isDualToneEnabled_) {
1218         std::lock_guard<std::mutex> lock(dualToneMutex_);
1219         if (dualToneStream_ != nullptr) {
1220             dualToneStream_->Drain(stopFlag);
1221         }
1222     }
1223     return SUCCESS;
1224 }
1225 
Stop()1226 int32_t RendererInServer::Stop()
1227 {
1228     AUDIO_INFO_LOG("Stop.");
1229     AudioXCollie audioXCollie(
1230         "RendererInServer::Stop", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1231             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1232     {
1233         std::unique_lock<std::mutex> lock(statusLock_);
1234         if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED && status_ != I_STATUS_DRAINING &&
1235             status_ != I_STATUS_STARTING) {
1236             AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1237             return ERR_ILLEGAL_STATE;
1238         }
1239         status_ = I_STATUS_STOPPING;
1240     }
1241     return StopInner();
1242 }
1243 
StopInner()1244 int32_t RendererInServer::StopInner()
1245 {
1246     if (standByEnable_) {
1247         AUDIO_INFO_LOG("sessionId: %{public}u call Stop while stand by", streamIndex_);
1248         CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
1249             ERR_OPERATION_FAILED, "stream status is nullptr");
1250         standByEnable_ = false;
1251         enterStandbyTime_ = 0;
1252         audioServerBuffer_->GetStreamStatus()->store(STREAM_STOPPED);
1253         if (playerDfx_) {
1254             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
1255         }
1256     }
1257     {
1258         std::lock_guard<std::mutex> lock(fadeoutLock_);
1259         AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
1260         fadeoutFlag_ = NO_FADING;
1261     }
1262     GetEAC3ControlParam();
1263     int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1264         IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop();
1265     {
1266         std::lock_guard<std::mutex> lock(dupMutex_);
1267         for (auto &capInfo : captureInfos_) {
1268             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1269                 capInfo.second.dupStream->Stop();
1270             }
1271         }
1272     }
1273     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1274         //Joint judgment ensures that there is a double ring and there is a stream to enter.
1275         stream_->SetAudioEffectMode(effectModeWhenDual_);
1276         std::lock_guard<std::mutex> lock(dualToneMutex_);
1277         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1278         if (dualToneStream_ != nullptr) {
1279             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1280             //modified elsewhere, it was decided again after the lock was awarded.
1281             dualToneStream_->Stop();
1282         }
1283     }
1284     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
1285     CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_STOP);
1286     audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_STOP, false);
1287     StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1288     AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(streamIndex_);
1289     return SUCCESS;
1290 }
1291 
Release(bool isSwitchStream)1292 int32_t RendererInServer::Release(bool isSwitchStream)
1293 {
1294     AUDIO_INFO_LOG("Start release");
1295     AudioXCollie audioXCollie(
1296         "RendererInServer::Release", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1297             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1298     {
1299         std::unique_lock<std::mutex> lock(statusLock_);
1300         if (status_ == I_STATUS_RELEASED) {
1301             AUDIO_INFO_LOG("Already released");
1302             return SUCCESS;
1303         }
1304     }
1305 
1306     if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1307         AudioService::GetInstance()->SetDecMaxRendererStreamCnt();
1308         AudioService::GetInstance()->CleanAppUseNumMap(processConfig_.appInfo.appUid);
1309     }
1310 
1311     int32_t ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_RELEASE);
1312     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy remove client failed, reason: %{public}d", ret);
1313     StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1314     ret = IStreamManager::GetPlaybackManager(managerType_).ReleaseRender(streamIndex_);
1315 
1316     AudioVolume::GetInstance()->RemoveStreamVolume(streamIndex_);
1317     AudioService::GetInstance()->RemoveRenderer(streamIndex_, isSwitchStream);
1318     if (ret < 0) {
1319         AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
1320         status_ = I_STATUS_INVALID;
1321         return ret;
1322     }
1323     if (status_ != I_STATUS_STOPPING &&
1324         status_ != I_STATUS_STOPPED) {
1325         HandleOperationStopped(RENDERER_STAGE_STOP_BY_RELEASE);
1326     }
1327     status_ = I_STATUS_RELEASED;
1328     DisableAllInnerCap();
1329     if (isDualToneEnabled_) {
1330         DisableDualTone();
1331     }
1332     return SUCCESS;
1333 }
1334 
DisableAllInnerCap()1335 int32_t RendererInServer::DisableAllInnerCap()
1336 {
1337     std::lock_guard<std::mutex> lock(dupMutex_);
1338     for (auto &capInfo : captureInfos_) {
1339         if (capInfo.second.isInnerCapEnabled) {
1340             DisableInnerCapHandle(capInfo.first);
1341         }
1342     }
1343     captureInfos_.clear();
1344     return SUCCESS;
1345 }
1346 
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)1347 int32_t RendererInServer::GetAudioTime(uint64_t &framePos, uint64_t &timestamp)
1348 {
1349     if (status_ == I_STATUS_STOPPED) {
1350         AUDIO_WARNING_LOG("Current status is stopped");
1351         return ERR_ILLEGAL_STATE;
1352     }
1353     stream_->GetStreamFramesWritten(framePos);
1354     stream_->GetCurrentTimeStamp(timestamp);
1355     if (resetTime_) {
1356         resetTime_ = false;
1357         resetTimestamp_ = timestamp;
1358     }
1359     return SUCCESS;
1360 }
1361 
GetAudioPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency,int32_t base)1362 int32_t RendererInServer::GetAudioPosition(uint64_t &framePos, uint64_t &timestamp, uint64_t &latency, int32_t base)
1363 {
1364     if (status_ == I_STATUS_STOPPED) {
1365         AUDIO_PRERELEASE_LOGW("Current status is stopped");
1366         return ERR_ILLEGAL_STATE;
1367     }
1368     stream_->GetCurrentPosition(framePos, timestamp, latency, base);
1369     return SUCCESS;
1370 }
1371 
GetSpeedPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency,int32_t base)1372 int32_t RendererInServer::GetSpeedPosition(uint64_t &framePos, uint64_t &timestamp, uint64_t &latency, int32_t base)
1373 {
1374     CHECK_AND_RETURN_RET_LOG(status_ != I_STATUS_STOPPED, ERR_ILLEGAL_STATE, "Current status is stopped");
1375     return stream_->GetSpeedPosition(framePos, timestamp, latency, base);
1376 }
1377 
GetLatency(uint64_t & latency)1378 int32_t RendererInServer::GetLatency(uint64_t &latency)
1379 {
1380     std::unique_lock<std::mutex> lock(statusLock_);
1381     if (managerType_ == DIRECT_PLAYBACK) {
1382         latency = IStreamManager::GetPlaybackManager(managerType_).GetLatency();
1383         return SUCCESS;
1384     }
1385     return stream_->GetLatency(latency);
1386 }
1387 
SetRate(int32_t rate)1388 int32_t RendererInServer::SetRate(int32_t rate)
1389 {
1390     return stream_->SetRate(rate);
1391 }
1392 
SetLowPowerVolume(float volume)1393 int32_t RendererInServer::SetLowPowerVolume(float volume)
1394 {
1395     if (volume < MIN_FLOAT_VOLUME || volume > MAX_FLOAT_VOLUME) {
1396         AUDIO_ERR_LOG("invalid volume:%{public}f", volume);
1397         return ERR_INVALID_PARAM;
1398     }
1399     std::string currentTime = GetTime();
1400     AUDIO_INFO_LOG("SetLowPowerVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1401         volume, streamIndex_, currentTime.c_str());
1402     AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(volume, streamIndex_, currentTime,
1403         static_cast<uint32_t>(AdjustStreamVolume::LOW_POWER_VOLUME_INFO));
1404 
1405     lowPowerVolume_ = volume;
1406     AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(streamIndex_, volume);
1407     {
1408         std::lock_guard<std::mutex> lock(dupMutex_);
1409         for (auto &capInfo : captureInfos_) {
1410             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1411                 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(
1412                     capInfo.second.dupStream->GetStreamIndex(), volume);
1413             }
1414         }
1415     }
1416     if (isDualToneEnabled_) {
1417         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, volume);
1418     }
1419     if (offloadEnable_) {
1420         OffloadSetVolumeInner();
1421     }
1422     return SUCCESS;
1423 }
1424 
GetLowPowerVolume(float & volume)1425 int32_t RendererInServer::GetLowPowerVolume(float &volume)
1426 {
1427     volume = lowPowerVolume_;
1428     return SUCCESS;
1429 }
1430 
SetAudioEffectMode(int32_t effectMode)1431 int32_t RendererInServer::SetAudioEffectMode(int32_t effectMode)
1432 {
1433     if (isDualToneEnabled_) {
1434         effectModeWhenDual_ = effectMode;
1435         return SUCCESS;
1436     }
1437     return stream_->SetAudioEffectMode(effectMode);
1438 }
1439 
GetAudioEffectMode(int32_t & effectMode)1440 int32_t RendererInServer::GetAudioEffectMode(int32_t &effectMode)
1441 {
1442     return stream_->GetAudioEffectMode(effectMode);
1443 }
1444 
SetPrivacyType(int32_t privacyType)1445 int32_t RendererInServer::SetPrivacyType(int32_t privacyType)
1446 {
1447     return stream_->SetPrivacyType(privacyType);
1448 }
1449 
GetPrivacyType(int32_t & privacyType)1450 int32_t RendererInServer::GetPrivacyType(int32_t &privacyType)
1451 {
1452     return stream_->GetPrivacyType(privacyType);
1453 }
1454 
EnableInnerCap(int32_t innerCapId)1455 int32_t RendererInServer::EnableInnerCap(int32_t innerCapId)
1456 {
1457     // in plan
1458     int32_t ret = InitDupStream(innerCapId);
1459     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dup stream failed");
1460     return SUCCESS;
1461 }
1462 
DisableInnerCap(int32_t innerCapId)1463 int32_t RendererInServer::DisableInnerCap(int32_t innerCapId)
1464 {
1465     std::lock_guard<std::mutex> lock(dupMutex_);
1466     if (!captureInfos_.count(innerCapId) || !captureInfos_[innerCapId].isInnerCapEnabled) {
1467         AUDIO_WARNING_LOG("InnerCap is already disabled.capId:%{public}d", innerCapId);
1468         return ERR_INVALID_OPERATION;
1469     }
1470     return DisableInnerCapHandle(innerCapId);
1471 }
1472 
DisableInnerCapHandle(int32_t innerCapId)1473 int32_t RendererInServer::DisableInnerCapHandle(int32_t innerCapId)
1474 {
1475     captureInfos_[innerCapId].isInnerCapEnabled = false;
1476     AUDIO_INFO_LOG("Disable dup renderer %{public}u with status: %{public}d", streamIndex_, status_.load());
1477     // in plan: call stop?
1478     if (captureInfos_[innerCapId].dupStream != nullptr) {
1479         uint32_t dupStreamIndex = captureInfos_[innerCapId].dupStream->GetStreamIndex();
1480         IStreamManager::GetDupPlaybackManager().ReleaseRender(dupStreamIndex);
1481         AudioVolume::GetInstance()->RemoveStreamVolume(dupStreamIndex);
1482         captureInfos_[innerCapId].dupStream = nullptr;
1483     }
1484     int32_t engineFlag = GetEngineFlag();
1485     if (engineFlag == 1) {
1486         DumpFileUtil::CloseDumpFile(&dumpDupIn_);
1487     }
1488     return SUCCESS;
1489 }
1490 
InitDupStream(int32_t innerCapId)1491 int32_t RendererInServer::InitDupStream(int32_t innerCapId)
1492 {
1493     AUDIO_INFO_LOG("InitDupStream for innerCapId:%{public}d", innerCapId);
1494     Trace trace(traceTag_ + "InitDupStream innerCapId:" + std::to_string(innerCapId));
1495     std::lock_guard<std::mutex> lock(dupMutex_);
1496     if (captureInfos_.count(innerCapId) && captureInfos_[innerCapId].isInnerCapEnabled) {
1497         AUDIO_INFO_LOG("InnerCap is already enabled,id:%{public}d", innerCapId);
1498         return SUCCESS;
1499     }
1500     auto &capInfo = captureInfos_[innerCapId];
1501     AudioProcessConfig dupConfig = processConfig_;
1502     dupConfig.innerCapId = innerCapId;
1503     int32_t ret = IStreamManager::GetDupPlaybackManager().CreateRender(dupConfig, capInfo.dupStream);
1504     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && capInfo.dupStream != nullptr,
1505         ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1506     uint32_t dupStreamIndex = capInfo.dupStream->GetStreamIndex();
1507     bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1508     StreamVolumeParams streamVolumeParams = { dupStreamIndex, processConfig_.streamType,
1509         processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1510         isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
1511     AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
1512     innerCapIdToDupStreamCallbackMap_[innerCapId] = std::make_shared<StreamCallbacks>(dupStreamIndex);
1513     int32_t engineFlag = GetEngineFlag();
1514     if (engineFlag == 1) {
1515         ret = CreateDupBufferInner(innerCapId);
1516         dumpDupInFileName_ = std::to_string(dupStreamIndex) + "_dup_in_" + ".pcm";
1517         DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupInFileName_, &dumpDupIn_);
1518         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Config dup buffer failed");
1519     }
1520     // todo check index
1521     capInfo.dupStream->RegisterStatusCallback(innerCapIdToDupStreamCallbackMap_[innerCapId]);
1522     capInfo.dupStream->RegisterWriteCallback(innerCapIdToDupStreamCallbackMap_[innerCapId]);
1523 
1524     AUDIO_INFO_LOG("Dup Renderer %{public}u with status: %{public}d", streamIndex_, status_.load());
1525     capInfo.isInnerCapEnabled = true;
1526     InitDupStreamVolume(dupStreamIndex);
1527     capInfo.dupStream->SetLoudnessGain(loudnessGain_);
1528 
1529     if (status_ == I_STATUS_STARTED) {
1530         AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dup stream", streamIndex_);
1531         capInfo.dupStream->Start();
1532 
1533         if (offloadEnable_) {
1534             renderEmptyCountForInnerCap_ = OFFLOAD_INNER_CAP_PREBUF;
1535         }
1536     }
1537     return SUCCESS;
1538 }
1539 
InitDupStreamVolume(uint32_t dupStreamIndex)1540 int32_t RendererInServer::InitDupStreamVolume(uint32_t dupStreamIndex)
1541 {
1542     if (audioServerBuffer_ != nullptr) {
1543         float clientVolume = audioServerBuffer_->GetStreamVolume();
1544         float duckFactor = audioServerBuffer_->GetDuckFactor();
1545         bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1546         // If some factors are not needed, remove them.
1547         AudioVolume::GetInstance()->SetStreamVolume(dupStreamIndex, clientVolume);
1548         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dupStreamIndex, duckFactor);
1549         AudioVolume::GetInstance()->SetStreamVolumeMute(dupStreamIndex, isMuted);
1550         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dupStreamIndex, lowPowerVolume_);
1551     }
1552     return SUCCESS;
1553 }
1554 
EnableDualTone()1555 int32_t RendererInServer::EnableDualTone()
1556 {
1557     if (isDualToneEnabled_) {
1558         AUDIO_INFO_LOG("DualTone is already enabled");
1559         return SUCCESS;
1560     }
1561     int32_t ret = InitDualToneStream();
1562     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dual tone stream failed");
1563     return SUCCESS;
1564 }
1565 
DisableDualTone()1566 int32_t RendererInServer::DisableDualTone()
1567 {
1568     std::lock_guard<std::mutex> lock(dualToneMutex_);
1569     if (!isDualToneEnabled_) {
1570         AUDIO_WARNING_LOG("DualTone is already disabled.");
1571         return ERR_INVALID_OPERATION;
1572     }
1573     isDualToneEnabled_ = false;
1574     AUDIO_INFO_LOG("Disable dual tone renderer:[%{public}u] with status: %{public}d",
1575         dualToneStreamIndex_, status_.load());
1576     IStreamManager::GetDualPlaybackManager().ReleaseRender(dualToneStreamIndex_);
1577     AudioVolume::GetInstance()->RemoveStreamVolume(dualToneStreamIndex_);
1578     dualToneStream_ = nullptr;
1579 
1580     return ERROR;
1581 }
1582 
InitDualToneStream()1583 int32_t RendererInServer::InitDualToneStream()
1584 {
1585     {
1586         std::lock_guard<std::mutex> lock(dualToneMutex_);
1587 
1588         int32_t ret = IStreamManager::GetDualPlaybackManager().CreateRender(processConfig_, dualToneStream_);
1589         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && dualToneStream_ != nullptr,
1590             ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1591         dualToneStreamIndex_ = dualToneStream_->GetStreamIndex();
1592         AUDIO_INFO_LOG("init dual tone renderer:[%{public}u]", dualToneStreamIndex_);
1593         bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1594         StreamVolumeParams streamVolumeParams = { dualToneStreamIndex_, processConfig_.streamType,
1595             processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1596             isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
1597         AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
1598 
1599         isDualToneEnabled_ = true;
1600     }
1601 
1602     if (audioServerBuffer_ != nullptr) {
1603         float clientVolume = audioServerBuffer_->GetStreamVolume();
1604         float duckFactor = audioServerBuffer_->GetDuckFactor();
1605         bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1606         // If some factors are not needed, remove them.
1607         AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1608         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1609         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1610         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, lowPowerVolume_);
1611     }
1612     if (status_ == I_STATUS_STARTED) {
1613         AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dual stream", dualToneStreamIndex_);
1614         stream_->GetAudioEffectMode(effectModeWhenDual_);
1615         stream_->SetAudioEffectMode(EFFECT_NONE);
1616         std::lock_guard<std::mutex> lock(dualToneMutex_);
1617         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1618         if (dualToneStream_ != nullptr) {
1619             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1620             //modified elsewhere, it was decided again after the lock was awarded.
1621             dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1622             dualToneStream_->Start();
1623         }
1624     }
1625     return SUCCESS;
1626 }
1627 
StreamCallbacks(uint32_t streamIndex)1628 StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex)
1629 {
1630     AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_);
1631     int32_t engineFlag = GetEngineFlag();
1632     if (engineFlag == 1) {
1633         dumpDupOutFileName_ = std::to_string(streamIndex_) + "_dup_out_" + ".pcm";
1634         DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupOutFileName_, &dumpDupOut_);
1635     }
1636 }
1637 
~StreamCallbacks()1638 StreamCallbacks::~StreamCallbacks()
1639 {
1640     int32_t engineFlag = GetEngineFlag();
1641     if (engineFlag == 1) {
1642         DumpFileUtil::CloseDumpFile(&dumpDupOut_);
1643     }
1644 }
1645 
OnStatusUpdate(IOperation operation)1646 void StreamCallbacks::OnStatusUpdate(IOperation operation)
1647 {
1648     AUDIO_INFO_LOG("DupStream %{public}u recv operation: %{public}d", streamIndex_, operation);
1649 }
1650 
OnWriteData(size_t length)1651 int32_t StreamCallbacks::OnWriteData(size_t length)
1652 {
1653     Trace trace("DupStream::OnWriteData length " + std::to_string(length));
1654     return SUCCESS;
1655 }
1656 
OnWriteData(int8_t * inputData,size_t requestDataLen)1657 int32_t StreamCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen)
1658 {
1659     Trace trace("DupStream::OnWriteData length " + std::to_string(requestDataLen));
1660     int32_t engineFlag = GetEngineFlag();
1661     if (engineFlag == 1 && dupRingBuffer_ != nullptr) {
1662         std::unique_ptr<AudioRingCache> &dupBuffer = dupRingBuffer_;
1663         // no need mutex
1664         // todo wait readable
1665         AUDIO_INFO_LOG("running");
1666         OptResult result = dupBuffer->GetReadableSize();
1667         CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1668             "dupBuffer get readable size failed, size is:%{public}zu", result.size);
1669         if (result.size == 0 || result.size < requestDataLen) {
1670             recoveryAntiShakeBufferCount_ = DUP_RECOVERY_AUTISHAKE_BUFFER_COUNT;
1671             AUDIO_INFO_LOG("Readable size is invaild, result.size:%{public}zu, requstDataLen:%{public}zu",
1672                 result.size, requestDataLen);
1673             return ERROR;
1674         }
1675         if (recoveryAntiShakeBufferCount_ > 0) {
1676             recoveryAntiShakeBufferCount_--;
1677             AUDIO_INFO_LOG("need recovery data anti-shake, no onWriteData, recoveryAntiShakeBufferCount_: %{public}d",
1678                 recoveryAntiShakeBufferCount_);
1679             return ERROR;
1680         }
1681         AUDIO_DEBUG_LOG("requstDataLen is:%{public}zu readSize is:%{public}zu", requestDataLen, result.size);
1682         result = dupBuffer->Dequeue({reinterpret_cast<uint8_t *>(inputData), requestDataLen});
1683         CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "dupBuffer dequeue failed");
1684         DumpFileUtil::WriteDumpFile(dumpDupOut_, static_cast<void *>(inputData), requestDataLen);
1685     }
1686     return SUCCESS;
1687 }
1688 
GetAvailableSize(size_t & length)1689 int32_t StreamCallbacks::GetAvailableSize(size_t &length)
1690 {
1691     if (dupRingBuffer_ == nullptr) {
1692         AUDIO_ERR_LOG("nullptr");
1693         return ERROR;
1694     }
1695 
1696     OptResult result = dupRingBuffer_->GetReadableSize();
1697     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1698         "get readable size failed, size is:%{public}zu", result.size);
1699 
1700     length = result.size;
1701     return SUCCESS;
1702 }
1703 
GetDupRingBuffer()1704 std::unique_ptr<AudioRingCache>& StreamCallbacks::GetDupRingBuffer()
1705 {
1706     return dupRingBuffer_;
1707 }
1708 
SetOffloadMode(int32_t state,bool isAppBack)1709 int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack)
1710 {
1711     int32_t ret = stream_->SetOffloadMode(state, isAppBack);
1712     {
1713         std::lock_guard<std::mutex> lock(dupMutex_);
1714         for (auto &capInfo : captureInfos_) {
1715             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1716                 capInfo.second.dupStream->UpdateMaxLength(350); // 350 for cover offload
1717             }
1718         }
1719     }
1720     if (isDualToneEnabled_) {
1721         std::lock_guard<std::mutex> lock(dualToneMutex_);
1722         if (dualToneStream_ != nullptr) {
1723             dualToneStream_->UpdateMaxLength(350); // 350 for cover offload
1724         }
1725     }
1726     return ret;
1727 }
1728 
UnsetOffloadMode()1729 int32_t RendererInServer::UnsetOffloadMode()
1730 {
1731     int32_t ret = stream_->UnsetOffloadMode();
1732     {
1733         std::lock_guard<std::mutex> lock(dupMutex_);
1734         for (auto &capInfo : captureInfos_) {
1735             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1736                 capInfo.second.dupStream->UpdateMaxLength(20); // 20 for unset offload
1737             }
1738         }
1739     }
1740     if (isDualToneEnabled_) {
1741         std::lock_guard<std::mutex> lock(dualToneMutex_);
1742         if (dualToneStream_ != nullptr) {
1743             dualToneStream_->UpdateMaxLength(20); // 20 for cover offload
1744         }
1745     }
1746     return ret;
1747 }
1748 
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)1749 int32_t RendererInServer::GetOffloadApproximatelyCacheTime(uint64_t &timestamp, uint64_t &paWriteIndex,
1750     uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
1751 {
1752     return stream_->GetOffloadApproximatelyCacheTime(timestamp, paWriteIndex, cacheTimeDsp, cacheTimePa);
1753 }
1754 
OffloadSetVolumeInner()1755 int32_t RendererInServer::OffloadSetVolumeInner()
1756 {
1757     struct VolumeValues volumes = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
1758     float volume = AudioVolume::GetInstance()->GetVolume(streamIndex_, processConfig_.streamType, "offload", &volumes);
1759     AUDIO_INFO_LOG("sessionID %{public}u volume: %{public}f", streamIndex_, volume);
1760     if (!IsVolumeSame(volumes.volumeHistory, volume, AUDIO_VOLOMUE_EPSILON)) {
1761         AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, volume);
1762         AudioVolume::GetInstance()->Monitor(streamIndex_, true);
1763     }
1764     return stream_->OffloadSetVolume(volume);
1765 }
1766 
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)1767 int32_t RendererInServer::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
1768 {
1769     return stream_->UpdateSpatializationState(spatializationEnabled, headTrackingEnabled);
1770 }
1771 
GetStreamManagerType() const1772 int32_t RendererInServer::GetStreamManagerType() const noexcept
1773 {
1774     return managerType_ == DIRECT_PLAYBACK ? AUDIO_DIRECT_MANAGER_TYPE : AUDIO_NORMAL_MANAGER_TYPE;
1775 }
1776 
IsHighResolution() const1777 bool RendererInServer::IsHighResolution() const noexcept
1778 {
1779     Trace trace("CheckHighResolution");
1780     if (processConfig_.deviceType != DEVICE_TYPE_WIRED_HEADSET &&
1781         processConfig_.deviceType != DEVICE_TYPE_USB_HEADSET) {
1782         AUDIO_INFO_LOG("normal stream,device type:%{public}d", processConfig_.deviceType);
1783         return false;
1784     }
1785     if (processConfig_.streamType != STREAM_MUSIC || processConfig_.streamInfo.samplingRate < SAMPLE_RATE_48000 ||
1786         processConfig_.streamInfo.format < SAMPLE_S24LE) {
1787         AUDIO_INFO_LOG("normal stream because stream info");
1788         return false;
1789     }
1790     if (processConfig_.streamInfo.samplingRate > SAMPLE_RATE_192000) {
1791         AUDIO_INFO_LOG("sample rate over 192k");
1792         return false;
1793     }
1794     if (IStreamManager::GetPlaybackManager(DIRECT_PLAYBACK).GetStreamCount() > 0) {
1795         AUDIO_INFO_LOG("high resolution exist.");
1796         return false;
1797     }
1798     return true;
1799 }
1800 
SetSilentModeAndMixWithOthers(bool on)1801 int32_t RendererInServer::SetSilentModeAndMixWithOthers(bool on)
1802 {
1803     silentModeAndMixWithOthers_ = on;
1804     bool isMuted = (isMuted_ || on || muteFlag_);
1805     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1806     {
1807         std::lock_guard<std::mutex> lock(dupMutex_);
1808         for (auto &capInfo : captureInfos_) {
1809             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1810                 AudioVolume::GetInstance()->SetStreamVolumeMute(
1811                     capInfo.second.dupStream->GetStreamIndex(), isMuted);
1812             }
1813         }
1814     }
1815     if (isDualToneEnabled_) {
1816         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1817     }
1818     if (offloadEnable_) {
1819         OffloadSetVolumeInner();
1820     }
1821     AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
1822     return SUCCESS;
1823 }
1824 
SetClientVolume()1825 int32_t RendererInServer::SetClientVolume()
1826 {
1827     if (audioServerBuffer_ == nullptr || playerDfx_ == nullptr) {
1828         AUDIO_WARNING_LOG("buffer in not inited");
1829         return ERROR;
1830     }
1831     float clientVolume = audioServerBuffer_->GetStreamVolume();
1832     std::string currentTime = GetTime();
1833     AUDIO_INFO_LOG("SetVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1834         clientVolume, streamIndex_, currentTime.c_str());
1835     AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(clientVolume, streamIndex_, currentTime,
1836         static_cast<uint32_t>(AdjustStreamVolume::STREAM_VOLUME_INFO));
1837     int32_t ret = stream_->SetClientVolume(clientVolume);
1838     SetStreamVolumeInfoForEnhanceChain();
1839     AudioVolume::GetInstance()->SetStreamVolume(streamIndex_, clientVolume);
1840     {
1841         std::lock_guard<std::mutex> lock(dupMutex_);
1842         for (auto &capInfo : captureInfos_) {
1843             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1844                 AudioVolume::GetInstance()->SetStreamVolume(
1845                     capInfo.second.dupStream->GetStreamIndex(), clientVolume);
1846             }
1847         }
1848     }
1849     if (isDualToneEnabled_) {
1850         AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1851     }
1852     if (offloadEnable_) {
1853         OffloadSetVolumeInner();
1854     }
1855 
1856     RendererStage stage = static_cast<size_t>(clientVolume) == 0 ?
1857         RENDERER_STAGE_SET_VOLUME_ZERO : RENDERER_STAGE_SET_VOLUME_NONZERO;
1858     playerDfx_->WriteDfxActionMsg(streamIndex_, stage);
1859     return ret;
1860 }
1861 
SetLoudnessGain(float loudnessGain)1862 int32_t RendererInServer::SetLoudnessGain(float loudnessGain)
1863 {
1864     loudnessGain_ = loudnessGain;
1865     int32_t ret = stream_->SetLoudnessGain(loudnessGain);
1866     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "setloudnessGain failed");
1867     {
1868         std::lock_guard<std::mutex> lock(dupMutex_);
1869         for (auto &capInfo : captureInfos_) {
1870             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1871                 ret += capInfo.second.dupStream->SetLoudnessGain(loudnessGain);
1872             }
1873         }
1874     }
1875     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "setloudnessGain failed during capture, error: %{public}d", ret);
1876     return SUCCESS;
1877 }
1878 
SetMute(bool isMute)1879 int32_t RendererInServer::SetMute(bool isMute)
1880 {
1881     isMuted_ = isMute;
1882     AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", isMute);
1883     bool isMuted = (isMute || silentModeAndMixWithOthers_ || muteFlag_);
1884     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1885     {
1886         std::lock_guard<std::mutex> lock(dupMutex_);
1887         for (auto &capInfo : captureInfos_) {
1888             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1889                 AudioVolume::GetInstance()->SetStreamVolumeMute(
1890                     capInfo.second.dupStream->GetStreamIndex(), isMuted);
1891             }
1892         }
1893     }
1894     if (isDualToneEnabled_) {
1895         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1896     }
1897     if (offloadEnable_) {
1898         OffloadSetVolumeInner();
1899     }
1900     return SUCCESS;
1901 }
1902 
SetDuckFactor(float duckFactor)1903 int32_t RendererInServer::SetDuckFactor(float duckFactor)
1904 {
1905     if (duckFactor < MIN_FLOAT_VOLUME || duckFactor > MAX_FLOAT_VOLUME) {
1906         AUDIO_ERR_LOG("invalid duck volume:%{public}f", duckFactor);
1907         return ERR_INVALID_PARAM;
1908     }
1909 
1910     std::string currentTime = GetTime();
1911     AUDIO_INFO_LOG("SetDuckVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1912         duckFactor, streamIndex_, currentTime.c_str());
1913     AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(duckFactor, streamIndex_, currentTime,
1914         static_cast<uint32_t>(AdjustStreamVolume::DUCK_VOLUME_INFO));
1915 
1916     AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(streamIndex_, duckFactor);
1917     {
1918         std::lock_guard<std::mutex> lock(dupMutex_);
1919         for (auto &capInfo : captureInfos_) {
1920             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1921                 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(
1922                     capInfo.second.dupStream->GetStreamIndex(), duckFactor);
1923             }
1924         }
1925     }
1926     if (isDualToneEnabled_) {
1927         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1928     }
1929     if (offloadEnable_) {
1930         OffloadSetVolumeInner();
1931     }
1932     return SUCCESS;
1933 }
1934 
SetStreamVolumeInfoForEnhanceChain()1935 int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain()
1936 {
1937     uint32_t sessionId = streamIndex_;
1938     float streamVolume = audioServerBuffer_->GetStreamVolume();
1939     int32_t engineFlag = GetEngineFlag();
1940     if (engineFlag == 1) {
1941         return HPAE::IHpaeManager::GetHpaeManager().SetStreamVolumeInfo(sessionId, streamVolume);
1942     } else {
1943         AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
1944         CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr");
1945         int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume);
1946         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed");
1947         return ret;
1948     }
1949 }
1950 
OnDataLinkConnectionUpdate(IOperation operation)1951 void RendererInServer::OnDataLinkConnectionUpdate(IOperation operation)
1952 {
1953     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
1954     CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr");
1955     switch (operation) {
1956         case OPERATION_DATA_LINK_CONNECTING:
1957             AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTING received");
1958             stateListener->OnOperationHandled(DATA_LINK_CONNECTING, 0);
1959             break;
1960         case OPERATION_DATA_LINK_CONNECTED:
1961             AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTED received");
1962             stateListener->OnOperationHandled(DATA_LINK_CONNECTED, 0);
1963             break;
1964         default:
1965             return;
1966     }
1967 }
1968 
GetActualStreamManagerType() const1969 int32_t RendererInServer::GetActualStreamManagerType() const noexcept
1970 {
1971     return managerType_;
1972 }
1973 
GetStatusStr(IStatus status)1974 static std::string GetStatusStr(IStatus status)
1975 {
1976     switch (status) {
1977         case I_STATUS_INVALID:
1978             return "INVALID";
1979         case I_STATUS_IDLE:
1980             return "IDEL";
1981         case I_STATUS_STARTING:
1982             return "STARTING";
1983         case I_STATUS_STARTED:
1984             return "STARTED";
1985         case I_STATUS_PAUSING:
1986             return "PAUSING";
1987         case I_STATUS_PAUSED:
1988             return "PAUSED";
1989         case I_STATUS_FLUSHING_WHEN_STARTED:
1990             return "FLUSHING_WHEN_STARTED";
1991         case I_STATUS_FLUSHING_WHEN_PAUSED:
1992             return "FLUSHING_WHEN_PAUSED";
1993         case I_STATUS_FLUSHING_WHEN_STOPPED:
1994             return "FLUSHING_WHEN_STOPPED";
1995         case I_STATUS_DRAINING:
1996             return "DRAINING";
1997         case I_STATUS_DRAINED:
1998             return "DRAINED";
1999         case I_STATUS_STOPPING:
2000             return "STOPPING";
2001         case I_STATUS_STOPPED:
2002             return "STOPPED";
2003         case I_STATUS_RELEASING:
2004             return "RELEASING";
2005         case I_STATUS_RELEASED:
2006             return "RELEASED";
2007         default:
2008             break;
2009     }
2010     return "NO_SUCH_STATUS";
2011 }
2012 
GetManagerTypeStr(ManagerType type)2013 static std::string GetManagerTypeStr(ManagerType type)
2014 {
2015     switch (type) {
2016         case PLAYBACK:
2017             return "Normal";
2018         case DUP_PLAYBACK:
2019             return "Dup Playback";
2020         case DUAL_PLAYBACK:
2021             return "DUAL Playback";
2022         case DIRECT_PLAYBACK:
2023             return "Direct";
2024         case VOIP_PLAYBACK:
2025             return "Voip";
2026         case RECORDER:
2027             return "Recorder";
2028         default:
2029             break;
2030     }
2031     return "NO_SUCH_TYPE";
2032 }
2033 
Dump(std::string & dumpString)2034 bool RendererInServer::Dump(std::string &dumpString)
2035 {
2036     if (managerType_ != DIRECT_PLAYBACK && managerType_ != VOIP_PLAYBACK) {
2037         return false;
2038     }
2039     // dump audio stream info
2040     dumpString += "audio stream info:\n";
2041     AppendFormat(dumpString, "  - session id:%u\n", streamIndex_);
2042     AppendFormat(dumpString, "  - appid:%d\n", processConfig_.appInfo.appPid);
2043     AppendFormat(dumpString, "  - stream type:%d\n", processConfig_.streamType);
2044 
2045     AppendFormat(dumpString, "  - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
2046     AppendFormat(dumpString, "  - channels: %u\n", processConfig_.streamInfo.channels);
2047     AppendFormat(dumpString, "  - format: %u\n", processConfig_.streamInfo.format);
2048     AppendFormat(dumpString, "  - device type: %u\n", processConfig_.deviceType);
2049     AppendFormat(dumpString, "  - sink type: %s\n", GetManagerTypeStr(managerType_).c_str());
2050 
2051     // dump status info
2052     AppendFormat(dumpString, "  - Current stream status: %s\n", GetStatusStr(status_.load()).c_str());
2053     if (audioServerBuffer_ != nullptr) {
2054         AppendFormat(dumpString, "  - Current read position: %u\n", audioServerBuffer_->GetCurReadFrame());
2055         AppendFormat(dumpString, "  - Current write position: %u\n", audioServerBuffer_->GetCurWriteFrame());
2056     }
2057 
2058     dumpString += "\n";
2059     return true;
2060 }
2061 
SetNonInterruptMute(const bool muteFlag)2062 void RendererInServer::SetNonInterruptMute(const bool muteFlag)
2063 {
2064     AUDIO_INFO_LOG("mute flag %{public}d", muteFlag);
2065     muteFlag_ = muteFlag;
2066     AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
2067 
2068     bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag);
2069     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
2070     {
2071         std::lock_guard<std::mutex> lock(dupMutex_);
2072         for (auto &captureInfo : captureInfos_) {
2073             if (captureInfo.second.isInnerCapEnabled && captureInfo.second.dupStream != nullptr) {
2074                 AudioVolume::GetInstance()->SetStreamVolumeMute(
2075                     captureInfo.second.dupStream->GetStreamIndex(), isMuted);
2076             }
2077         }
2078     }
2079     if (isDualToneEnabled_) {
2080         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
2081     }
2082     if (offloadEnable_) {
2083         OffloadSetVolumeInner();
2084     }
2085 }
2086 
RestoreSession(RestoreInfo restoreInfo)2087 RestoreStatus RendererInServer::RestoreSession(RestoreInfo restoreInfo)
2088 {
2089     RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
2090     if (restoreStatus == NEED_RESTORE) {
2091         audioServerBuffer_->SetRestoreInfo(restoreInfo);
2092     }
2093     audioServerBuffer_->WakeFutex();
2094     return restoreStatus;
2095 }
2096 
SetDefaultOutputDevice(const DeviceType defaultOutputDevice,bool skipForce)2097 int32_t RendererInServer::SetDefaultOutputDevice(const DeviceType defaultOutputDevice, bool skipForce)
2098 {
2099     return CoreServiceHandler::GetInstance().SetDefaultOutputDevice(defaultOutputDevice, streamIndex_,
2100         processConfig_.rendererInfo.streamUsage, status_ == I_STATUS_STARTED, skipForce);
2101 }
2102 
SetSourceDuration(int64_t duration)2103 int32_t RendererInServer::SetSourceDuration(int64_t duration)
2104 {
2105     sourceDuration_ = duration;
2106     return SUCCESS;
2107 }
2108 
GetDupRingBuffer()2109 std::unique_ptr<AudioRingCache>& RendererInServer::GetDupRingBuffer()
2110 {
2111     return dupRingBuffer_;
2112 }
2113 
CreateDupBufferInner(int32_t innerCapId)2114 int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId)
2115 {
2116     // todo dynamic
2117     if (innerCapIdToDupStreamCallbackMap_.find(innerCapId) == innerCapIdToDupStreamCallbackMap_.end() ||
2118         innerCapIdToDupStreamCallbackMap_[innerCapId] == nullptr ||
2119         innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr) {
2120         AUDIO_INFO_LOG("dup buffer already configed!");
2121         return SUCCESS;
2122     }
2123 
2124     auto &capInfo = captureInfos_[innerCapId];
2125     capInfo.dupStream->GetSpanSizePerFrame(dupSpanSizeInFrame_);
2126     if (offloadEnable_ == true) {
2127         dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN);
2128     } else {
2129         dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_COMMON_LEN/DUP_DEFAULT_LEN);
2130     }
2131 
2132     capInfo.dupStream->GetByteSizePerFrame(dupByteSizePerFrame_);
2133     if (dupSpanSizeInFrame_ == 0 || dupByteSizePerFrame_ == 0) {
2134         AUDIO_ERR_LOG("ERR_INVALID_PARAM");
2135         return ERR_INVALID_PARAM;
2136     }
2137     dupSpanSizeInByte_ = dupSpanSizeInFrame_ * dupByteSizePerFrame_;
2138     CHECK_AND_RETURN_RET_LOG(dupSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config dup buffer failed");
2139     AUDIO_INFO_LOG("dupTotalSizeInFrame_: %{public}zu, dupSpanSizeInFrame_: %{public}zu,"
2140         "dupByteSizePerFrame_:%{public}zu dupSpanSizeInByte_: %{public}zu,",
2141         dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_);
2142 
2143     // create dupBuffer in server
2144     innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() =
2145         AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_);
2146     CHECK_AND_RETURN_RET_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr,
2147         ERR_OPERATION_FAILED, "Create dup buffer failed");
2148     return SUCCESS;
2149 }
2150 
WriteDupBufferInner(const BufferDesc & bufferDesc,int32_t innerCapId)2151 int32_t RendererInServer::WriteDupBufferInner(const BufferDesc &bufferDesc, int32_t innerCapId)
2152 {
2153     size_t targetSize = bufferDesc.bufLength;
2154     if (innerCapIdToDupStreamCallbackMap_.find(innerCapId) == innerCapIdToDupStreamCallbackMap_.end() ||
2155         innerCapIdToDupStreamCallbackMap_[innerCapId] == nullptr ||
2156         innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() == nullptr) {
2157         AUDIO_INFO_LOG("dup buffer is nnullptr, failed WriteDupBuffer!");
2158         return ERROR;
2159     }
2160     OptResult result = innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->GetWritableSize();
2161     // todo get writeable size failed
2162     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
2163         "DupRingBuffer write invalid size is:%{public}zu", result.size);
2164     size_t writableSize = result.size;
2165     AUDIO_DEBUG_LOG("targetSize: %{public}zu, writableSize: %{public}zu", targetSize, writableSize);
2166     size_t writeSize = std::min(writableSize, targetSize);
2167     BufferWrap bufferWrap = {bufferDesc.buffer, writeSize};
2168     if (writeSize > 0) {
2169         result = innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->Enqueue(bufferWrap);
2170         if (result.ret != OPERATION_SUCCESS) {
2171             AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size);
2172         }
2173         DumpFileUtil::WriteDumpFile(dumpDupIn_, static_cast<void *>(bufferDesc.buffer), writeSize);
2174     }
2175     return SUCCESS;
2176 }
2177 
SetSpeed(float speed)2178 int32_t RendererInServer::SetSpeed(float speed)
2179 {
2180     CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "stream_ is null");
2181     return stream_->SetSpeed(speed);
2182 }
2183 
SetOffloadDataCallbackState(int32_t state)2184 int32_t RendererInServer::SetOffloadDataCallbackState(int32_t state)
2185 {
2186     return stream_->SetOffloadDataCallbackState(state);
2187 }
2188 
StopSession()2189 int32_t RendererInServer::StopSession()
2190 {
2191     CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_INVALID_PARAM, "audioServerBuffer_ is nullptr");
2192     audioServerBuffer_->SetStopFlag(true);
2193     return SUCCESS;
2194 }
2195 
SetAudioHapticsSyncId(const int32_t & audioHapticsSyncId)2196 int32_t RendererInServer::SetAudioHapticsSyncId(const int32_t &audioHapticsSyncId)
2197 {
2198     audioHapticsSyncId_.store(audioHapticsSyncId);
2199     return SUCCESS;
2200 }
2201 
UpdateLatestForWorkgroup(float systemVolume)2202 void RendererInServer::UpdateLatestForWorkgroup(float systemVolume)
2203 {
2204     latestForWorkgroup_.status = status_;
2205     latestForWorkgroup_.isInSilentState = isInSilentState_;
2206     latestForWorkgroup_.silentModeAndMixWithOthers = silentModeAndMixWithOthers_.load();
2207     latestForWorkgroup_.lastWriteStandbyEnableStatus = lastWriteStandbyEnableStatus_;
2208     latestForWorkgroup_.streamVolume = audioServerBuffer_->GetStreamVolume();
2209     latestForWorkgroup_.systemVolume = systemVolume;
2210     AUDIO_INFO_LOG("[WorkgroupInServer] pid = %{public}d, status_ = %{public}d, "
2211         "isInSilentState_ = %{public}d, "
2212         "silentModeAndMixWithOthers_ = %{public}d, "
2213         "lastWriteStandbyEnableStatus_ = %{public}d, "
2214         "streamVolume = %{public}f, "
2215         "systemVolume = %{public}f",
2216         processConfig_.appInfo.appPid, latestForWorkgroup_.status, latestForWorkgroup_.isInSilentState,
2217         latestForWorkgroup_.silentModeAndMixWithOthers, latestForWorkgroup_.lastWriteStandbyEnableStatus,
2218         latestForWorkgroup_.streamVolume, latestForWorkgroup_.systemVolume);
2219 }
2220 
CollectInfosForWorkgroup(float systemVolume)2221 bool RendererInServer::CollectInfosForWorkgroup(float systemVolume)
2222 {
2223     bool running = (status_ == I_STATUS_STARTED) ? true : false;
2224     float streamVolume = audioServerBuffer_->GetStreamVolume();
2225     bool haveStreamSound = (fabs(streamVolume) > AUDIO_VOLOMUE_EPSILON) ? true : false;
2226     bool haveSystemSound = (fabs(systemVolume) > AUDIO_VOLOMUE_EPSILON) ? true : false;
2227 
2228     if (!latestForWorkgroupInited_) {
2229         UpdateLatestForWorkgroup(systemVolume);
2230         latestForWorkgroupInited_ = true;
2231     }
2232     UpdateLatestForWorkgroup(systemVolume);
2233 
2234     return running && haveStreamSound && haveSystemSound &&
2235         !isInSilentState_ && !silentModeAndMixWithOthers_ && !lastWriteStandbyEnableStatus_;
2236 }
2237 
InitDupBuffer(int32_t innerCapId)2238 void RendererInServer::InitDupBuffer(int32_t innerCapId)
2239 {
2240     std::lock_guard<std::mutex> lock(dupMutex_);
2241     CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_.find(innerCapId) != innerCapIdToDupStreamCallbackMap_.end(),
2242         "innerCapIdToDupStreamCallbackMap_ is no find innerCapId: %{public}d", innerCapId);
2243     CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId] != nullptr,
2244         "innerCapIdToDupStreamCallbackMap_ is null, innerCapId: %{public}d", innerCapId);
2245     CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr,
2246         "DupRingBuffe is null, innerCapId: %{public}d", innerCapId);
2247     innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->
2248         ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false);
2249     AUDIO_INFO_LOG("InitDupBuffer success, innerCapId: %{public}d, stream sessionId: %{public}u",
2250         innerCapId, streamIndex_);
2251 }
2252 } // namespace AudioStandard
2253 } // namespace OHOS
2254