• 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 
41 namespace OHOS {
42 namespace AudioStandard {
43 namespace {
44     static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
45     static const int64_t MOCK_LATENCY = 45000000; // 45000000 -> 45ms
46     static const int64_t START_MIN_COST = 80000000; // 80000000 -> 80ms
47     static const int32_t NO_FADING = 0;
48     static const int32_t DO_FADINGOUT = 1;
49     static const int32_t FADING_OUT_DONE = 2;
50     static const float FADINGOUT_BEGIN = 1.0f;
51     static const float FADINGOUT_END = 0.0f;
52     static constexpr int32_t ONE_MINUTE = 60;
53     const int32_t MEDIA_UID = 1013;
54     const float AUDIO_VOLOMUE_EPSILON = 0.0001;
55     const int32_t OFFLOAD_INNER_CAP_PREBUF = 3;
56     constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S
57     constexpr int32_t DEFAULT_SPAN_SIZE = 1;
58     constexpr size_t MSEC_PER_SEC = 1000;
59 }
60 
RendererInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)61 RendererInServer::RendererInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
62     : processConfig_(processConfig)
63 {
64     streamListener_ = streamListener;
65     managerType_ = PLAYBACK;
66     if (processConfig_.callerUid == MEDIA_UID) {
67         isNeedFade_ = true;
68         oldAppliedVolume_ = MIN_FLOAT_VOLUME;
69     }
70 }
71 
~RendererInServer()72 RendererInServer::~RendererInServer()
73 {
74     if (status_ != I_STATUS_RELEASED) {
75         Release();
76     }
77     DumpFileUtil::CloseDumpFile(&dumpC2S_);
78 }
79 
ConfigServerBuffer()80 int32_t RendererInServer::ConfigServerBuffer()
81 {
82     if (audioServerBuffer_ != nullptr) {
83         AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
84         return SUCCESS;
85     }
86     stream_->GetSpanSizePerFrame(spanSizeInFrame_);
87     totalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE;
88     stream_->GetByteSizePerFrame(byteSizePerFrame_);
89     if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) {
90         AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
91         return ERR_INVALID_PARAM;
92     }
93 
94     spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_;
95     CHECK_AND_RETURN_RET_LOG(spanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config oh audio buffer failed");
96     AUDIO_INFO_LOG("totalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu, byteSizePerFrame_:%{public}zu "
97         "spanSizeInByte_: %{public}zu,", totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_, spanSizeInByte_);
98 
99     // create OHAudioBuffer in server
100     audioServerBuffer_ = OHAudioBuffer::CreateFromLocal(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_);
101     CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
102 
103     // we need to clear data buffer to avoid dirty data.
104     memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
105         audioServerBuffer_->GetDataSize());
106     int32_t ret = InitBufferStatus();
107     AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
108 
109     isBufferConfiged_ = true;
110     isInited_ = true;
111     return SUCCESS;
112 }
113 
InitBufferStatus()114 int32_t RendererInServer::InitBufferStatus()
115 {
116     if (audioServerBuffer_ == nullptr) {
117         AUDIO_ERR_LOG("InitBufferStatus failed, null buffer.");
118         return ERR_ILLEGAL_STATE;
119     }
120 
121     uint32_t spanCount = audioServerBuffer_->GetSpanCount();
122     AUDIO_INFO_LOG("InitBufferStatus: spanCount %{public}u", spanCount);
123     for (uint32_t i = 0; i < spanCount; i++) {
124         SpanInfo *spanInfo = audioServerBuffer_->GetSpanInfoByIndex(i);
125         if (spanInfo == nullptr) {
126             AUDIO_ERR_LOG("InitBufferStatus failed, null spaninfo");
127             return ERR_ILLEGAL_STATE;
128         }
129         spanInfo->spanStatus = SPAN_READ_DONE;
130         spanInfo->offsetInFrame = 0;
131 
132         spanInfo->readStartTime = 0;
133         spanInfo->readDoneTime = 0;
134 
135         spanInfo->writeStartTime = 0;
136         spanInfo->writeDoneTime = 0;
137 
138         spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
139         spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
140         spanInfo->isMute = false;
141     }
142     return SUCCESS;
143 }
144 
Init()145 int32_t RendererInServer::Init()
146 {
147     if (IsHighResolution()) {
148         Trace trace("current stream marked as high resolution");
149         managerType_ = DIRECT_PLAYBACK;
150         AUDIO_INFO_LOG("current stream marked as high resolution");
151     }
152 
153     if (processConfig_.rendererInfo.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) {
154         if (IStreamManager::GetPlaybackManager(VOIP_PLAYBACK).GetStreamCount() <= 0) {
155             AUDIO_INFO_LOG("current stream marked as VoIP direct stream");
156             managerType_ = VOIP_PLAYBACK;
157         } else {
158             AUDIO_WARNING_LOG("One VoIP direct stream has been created! Use normal mode.");
159         }
160     }
161 
162     int32_t ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
163     if (ret != SUCCESS && (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK)) {
164         Trace trace("high resolution create failed use normal replace");
165         managerType_ = PLAYBACK;
166         ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
167         AUDIO_INFO_LOG("high resolution create failed use normal replace");
168     }
169     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
170         "Construct rendererInServer failed: %{public}d", ret);
171     streamIndex_ = stream_->GetStreamIndex();
172     bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
173     AudioVolume::GetInstance()->AddStreamVolume(streamIndex_, processConfig_.streamType,
174         processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
175         isSystemApp, processConfig_.rendererInfo.volumeMode);
176     traceTag_ = "[" + std::to_string(streamIndex_) + "]RendererInServer"; // [100001]RendererInServer:
177     ret = ConfigServerBuffer();
178     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
179         "Construct rendererInServer failed: %{public}d", ret);
180     stream_->RegisterStatusCallback(shared_from_this());
181     stream_->RegisterWriteCallback(shared_from_this());
182 
183     // eg: /data/data/.pulse_dir/10000_100001_48000_2_1_server_in.pcm
184     AudioStreamInfo tempInfo = processConfig_.streamInfo;
185     dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
186         + "_renderer_server_in_" + std::to_string(tempInfo.samplingRate) + "_"
187         + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
188     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpC2S_);
189     playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, streamIndex_);
190 
191     return SUCCESS;
192 }
193 
CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)194 void RendererInServer::CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)
195 {
196     if (standbyEnable == lastWriteStandbyEnableStatus_) {
197         return;
198     }
199     lastWriteStandbyEnableStatus_ = standbyEnable;
200     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
201         Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
202         Media::MediaMonitor::BEHAVIOR_EVENT);
203     bean->Add("STREAMID", static_cast<int32_t>(streamIndex_));
204     bean->Add("STANDBY", standbyEnable ? 1 : 0);
205     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
206     std::unordered_map<std::string, std::string> payload;
207     payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
208     payload["sessionId"] = std::to_string(streamIndex_);
209     payload["isStandby"] = std::to_string(standbyEnable ? 1 : 0);
210     ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
211 }
212 
OnStatusUpdate(IOperation operation)213 void RendererInServer::OnStatusUpdate(IOperation operation)
214 {
215     AUDIO_INFO_LOG("%{public}u recv operation:%{public}d standByEnable_:%{public}s", streamIndex_, operation,
216         (standByEnable_ ? "true" : "false"));
217     Trace trace(traceTag_ + " OnStatusUpdate:" + std::to_string(operation));
218     CHECK_AND_RETURN_LOG(operation != OPERATION_RELEASED, "Stream already released");
219     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
220     CHECK_AND_RETURN_LOG((stateListener != nullptr && playerDfx_ != nullptr), "nullptr");
221     CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
222         "stream status is nullptr");
223     switch (operation) {
224         case OPERATION_STARTED:
225             HandleOperationStarted();
226             stateListener->OnOperationHandled(START_STREAM, 0);
227             break;
228         case OPERATION_PAUSED:
229             if (standByEnable_) {
230                 AUDIO_INFO_LOG("%{public}u recv stand-by paused", streamIndex_);
231                 audioServerBuffer_->GetStreamStatus()->store(STREAM_STAND_BY);
232                 CheckAndWriterRenderStreamStandbySysEvent(true);
233                 return;
234             }
235             status_ = I_STATUS_PAUSED;
236             stateListener->OnOperationHandled(PAUSE_STREAM, 0);
237             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_PAUSE_OK);
238             break;
239         case OPERATION_STOPPED:
240             status_ = I_STATUS_STOPPED;
241             stateListener->OnOperationHandled(STOP_STREAM, 0);
242             lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
243                 std::chrono::system_clock::now().time_since_epoch()).count();
244             lastWriteFrame_ = audioServerBuffer_->GetCurReadFrame() - lastWriteFrame_;
245             playerDfx_->WriteDfxStopMsg(streamIndex_, RENDERER_STAGE_STOP_OK,
246                 {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
247             break;
248         case OPERATION_FLUSHED:
249             HandleOperationFlushed();
250             stateListener->OnOperationHandled(FLUSH_STREAM, 0);
251             break;
252         case OPERATION_DRAINED:
253             // Client's StopAudioStream will call Drain first and then Stop. If server's drain times out,
254             // Stop will be completed first. After a period of time, when Drain's callback goes here,
255             // state of server should not be changed to STARTED while the client state is Stopped.
256             OnStatusUpdateExt(operation, stateListener);
257             break;
258         default:
259             OnStatusUpdateSub(operation);
260     }
261 }
262 
GetLastAudioDuration()263 int64_t RendererInServer::GetLastAudioDuration()
264 {
265     auto ret = lastStopTime_ - lastStartTime_;
266     return ret < 0 ? -1 : ret;
267 }
268 
OnStatusUpdateExt(IOperation operation,std::shared_ptr<IStreamListener> stateListener)269 void RendererInServer::OnStatusUpdateExt(IOperation operation, std::shared_ptr<IStreamListener> stateListener)
270 {
271     if (status_ == I_STATUS_DRAINING) {
272         status_ = I_STATUS_STARTED;
273         stateListener->OnOperationHandled(DRAIN_STREAM, 0);
274     }
275     afterDrain = true;
276 }
277 
HandleOperationStarted()278 void RendererInServer::HandleOperationStarted()
279 {
280     CHECK_AND_RETURN_LOG(playerDfx_ != nullptr, "nullptr");
281     CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
282         "stream status is nullptr");
283     if (standByEnable_) {
284         standByEnable_ = false;
285         AUDIO_INFO_LOG("%{public}u recv stand-by started", streamIndex_);
286         audioServerBuffer_->GetStreamStatus()->store(STREAM_RUNNING);
287         FutexTool::FutexWake(audioServerBuffer_->GetFutex());
288         playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
289     }
290     CheckAndWriterRenderStreamStandbySysEvent(false);
291     status_ = I_STATUS_STARTED;
292     startedTime_ = ClockTime::GetCurNano();
293 
294     lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
295         std::chrono::system_clock::now().time_since_epoch()).count();
296     lastWriteFrame_ = audioServerBuffer_->GetCurReadFrame();
297     lastWriteMuteFrame_ = 0;
298 }
299 
OnStatusUpdateSub(IOperation operation)300 void RendererInServer::OnStatusUpdateSub(IOperation operation)
301 {
302     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
303     switch (operation) {
304         case OPERATION_RELEASED:
305             stateListener->OnOperationHandled(RELEASE_STREAM, 0);
306             status_ = I_STATUS_RELEASED;
307             break;
308         case OPERATION_UNDERRUN:
309             AUDIO_INFO_LOG("Underrun: audioServerBuffer_->GetAvailableDataFrames(): %{public}d",
310                 audioServerBuffer_->GetAvailableDataFrames());
311             if (audioServerBuffer_->GetAvailableDataFrames() ==
312                 static_cast<int32_t>(DEFAULT_SPAN_SIZE * spanSizeInFrame_)) {
313                 AUDIO_INFO_LOG("Buffer is empty");
314                 needForceWrite_ = 0;
315             } else {
316                 AUDIO_INFO_LOG("Buffer is not empty");
317                 WriteData();
318             }
319             break;
320         case OPERATION_UNDERFLOW:
321             if (ClockTime::GetCurNano() - startedTime_ > START_MIN_COST) {
322                 underrunCount_++;
323                 audioServerBuffer_->SetUnderrunCount(underrunCount_);
324             }
325             StandByCheck(); // if stand by is enbaled here, stream will be paused and not recv UNDERFLOW any more.
326             break;
327         case OPERATION_SET_OFFLOAD_ENABLE:
328         case OPERATION_UNSET_OFFLOAD_ENABLE:
329             offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false;
330             stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0);
331             break;
332         default:
333             AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
334             status_ = I_STATUS_INVALID;
335     }
336 }
337 
StandByCheck()338 void RendererInServer::StandByCheck()
339 {
340     Trace trace(traceTag_ + " StandByCheck:standByCounter_:" + std::to_string(standByCounter_.load()));
341 
342     // msdp wait for uncertain time when waiting for bt reply, which may case stream change into standby mode.
343     // if client writes date when stream is changing into standby mode, it would cause drain fail problems.
344     // msdp promises to call api correctly to avoid power problems
345     if (processConfig_.rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_ULTRASONIC) {
346         return;
347     }
348     AUDIO_INFO_LOG("sessionId:%{public}u standByCounter_:%{public}u standByEnable_:%{public}s ", streamIndex_,
349         standByCounter_.load(), (standByEnable_ ? "true" : "false"));
350 
351     // direct standBy need not in here
352     if (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) {
353         return;
354     }
355 
356     if (standByEnable_) {
357         return;
358     }
359     standByCounter_++;
360     if (!ShouldEnableStandBy()) {
361         return;
362     }
363 
364     // call enable stand by
365     standByEnable_ = true;
366     enterStandbyTime_ = ClockTime::GetCurNano();
367     // PaAdapterManager::PauseRender will hold mutex, may cause dead lock with pa_lock
368     if (managerType_ == PLAYBACK) {
369         stream_->Pause(true);
370     }
371 
372     if (playerDfx_) {
373         playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_BEGIN);
374     }
375 }
376 
ShouldEnableStandBy()377 bool RendererInServer::ShouldEnableStandBy()
378 {
379     int64_t timeCost = ClockTime::GetCurNano() - lastWriteTime_;
380     uint32_t maxStandByCounter = 50; // for 20ms, 50 * 20 = 1000ms
381     int64_t timeLimit = 1000000000; // 1s
382     if (offloadEnable_) {
383         maxStandByCounter = 400; // for 20ms, 50 * 400 = 8000ms
384         timeLimit = 8 * AUDIO_NS_PER_SECOND; // for 20ms 8s
385     }
386     if (standByCounter_ >= maxStandByCounter && timeCost >= timeLimit) {
387         AUDIO_INFO_LOG("sessionId:%{public}u reach the limit of stand by: %{public}u time:%{public}" PRId64"ns",
388             streamIndex_, standByCounter_.load(), timeCost);
389         return true;
390     }
391     return false;
392 }
393 
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)394 int32_t RendererInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
395 {
396     Trace trace("RendererInServer::GetStandbyStatus:" + std::to_string(streamIndex_) + (standByEnable_ ? " Enabled" :
397         "Disabled"));
398     isStandby = standByEnable_;
399     if (isStandby) {
400         enterStandbyTime = enterStandbyTime_;
401     } else {
402         enterStandbyTime = 0;
403     }
404     return SUCCESS;
405 }
406 
HandleOperationFlushed()407 void RendererInServer::HandleOperationFlushed()
408 {
409     switch (status_) {
410         case I_STATUS_FLUSHING_WHEN_STARTED:
411             status_ = I_STATUS_STARTED;
412             break;
413         case I_STATUS_FLUSHING_WHEN_PAUSED:
414             status_ = I_STATUS_PAUSED;
415             break;
416         case I_STATUS_FLUSHING_WHEN_STOPPED:
417             status_ = I_STATUS_STOPPED;
418             break;
419         default:
420             AUDIO_WARNING_LOG("Invalid status before flusing");
421     }
422 }
423 
DequeueBuffer(size_t length)424 BufferDesc RendererInServer::DequeueBuffer(size_t length)
425 {
426     return stream_->DequeueBuffer(length);
427 }
428 
DoFadingOut(BufferDesc & bufferDesc)429 void RendererInServer::DoFadingOut(BufferDesc& bufferDesc)
430 {
431     std::lock_guard<std::mutex> lock(fadeoutLock_);
432     if (fadeoutFlag_ == DO_FADINGOUT) {
433         AUDIO_INFO_LOG("enter. format:%{public}u", processConfig_.streamInfo.format);
434         AudioChannel channel = processConfig_.streamInfo.channels;
435         ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, FADINGOUT_BEGIN, FADINGOUT_END);
436         int32_t ret = VolumeTools::Process(bufferDesc, processConfig_.streamInfo.format, mapVols);
437         if (ret != SUCCESS) {
438             AUDIO_WARNING_LOG("VolumeTools::Process failed: %{public}d", ret);
439         }
440         fadeoutFlag_ = FADING_OUT_DONE;
441         AUDIO_INFO_LOG("fadeoutFlag_ = FADING_OUT_DONE");
442     }
443 }
444 
IsInvalidBuffer(uint8_t * buffer,size_t bufferSize)445 bool RendererInServer::IsInvalidBuffer(uint8_t *buffer, size_t bufferSize)
446 {
447     bool isInvalid = false;
448     uint8_t ui8Data = 0;
449     int16_t i16Data = 0;
450     switch (processConfig_.streamInfo.format) {
451         case SAMPLE_U8:
452             CHECK_AND_RETURN_RET_LOG(bufferSize > 0, false, "buffer size is too small");
453             ui8Data = *buffer;
454             isInvalid = ui8Data == 0;
455             break;
456         case SAMPLE_S16LE:
457             CHECK_AND_RETURN_RET_LOG(bufferSize > 1, false, "buffer size is too small");
458             i16Data = *(reinterpret_cast<const int16_t*>(buffer));
459             isInvalid = i16Data == 0;
460             break;
461         default:
462             break;
463     }
464     return isInvalid;
465 }
466 
WriteMuteDataSysEvent(BufferDesc & bufferDesc)467 void RendererInServer::WriteMuteDataSysEvent(BufferDesc &bufferDesc)
468 {
469     int64_t muteFrameCnt = 0;
470     VolumeTools::CalcMuteFrame(bufferDesc, processConfig_.streamInfo, traceTag_, volumeDataCount_, muteFrameCnt);
471     lastWriteMuteFrame_ += muteFrameCnt;
472     if (silentModeAndMixWithOthers_) {
473         return;
474     }
475     if (IsInvalidBuffer(bufferDesc.buffer, bufferDesc.bufLength)) {
476         if (startMuteTime_ == 0) {
477             startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
478         }
479         std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
480         if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isInSilentState_) {
481             isInSilentState_ = true;
482             AUDIO_WARNING_LOG("write invalid data for some time in server");
483 
484             std::unordered_map<std::string, std::string> payload;
485             payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
486             payload["sessionId"] = std::to_string(streamIndex_);
487             payload["isSilent"] = std::to_string(true);
488             ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
489         }
490     } else {
491         if (startMuteTime_ != 0) {
492             startMuteTime_ = 0;
493         }
494         if (isInSilentState_) {
495             AUDIO_WARNING_LOG("begin write valid data in server");
496             isInSilentState_ = false;
497 
498             std::unordered_map<std::string, std::string> payload;
499             payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
500             payload["sessionId"] = std::to_string(streamIndex_);
501             payload["isSilent"] = std::to_string(false);
502             ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
503         }
504     }
505 }
506 
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)507 void RendererInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
508 {
509 #ifdef RESSCHE_ENABLE
510     AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
511     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
512 #endif
513 }
514 
VolumeHandle(BufferDesc & desc)515 void RendererInServer::VolumeHandle(BufferDesc &desc)
516 {
517     // volume process in server
518     if (audioServerBuffer_ == nullptr) {
519         AUDIO_WARNING_LOG("buffer in not inited");
520         return;
521     }
522     float applyVolume = 0.0f;
523     if (muteFlag_) {
524         applyVolume = 0.0f;
525     } else {
526         applyVolume = audioServerBuffer_->GetStreamVolume();
527     }
528     float duckVolume = audioServerBuffer_->GetDuckFactor();
529     float muteVolume = audioServerBuffer_->GetMuteFactor();
530     if (!IsVolumeSame(MAX_FLOAT_VOLUME, lowPowerVolume_, AUDIO_VOLOMUE_EPSILON)) {
531         applyVolume *= lowPowerVolume_;
532     }
533     if (!IsVolumeSame(MAX_FLOAT_VOLUME, duckVolume, AUDIO_VOLOMUE_EPSILON)) {
534         applyVolume *= duckVolume;
535     }
536     if (!IsVolumeSame(MAX_FLOAT_VOLUME, muteVolume, AUDIO_VOLOMUE_EPSILON)) {
537         applyVolume *= muteVolume;
538     }
539 
540     if (silentModeAndMixWithOthers_) {
541         applyVolume = 0.0f;
542     }
543 
544     //in plan: put system volume handle here
545     if (!IsVolumeSame(MAX_FLOAT_VOLUME, applyVolume, AUDIO_VOLOMUE_EPSILON) ||
546         !IsVolumeSame(oldAppliedVolume_, applyVolume, AUDIO_VOLOMUE_EPSILON)) {
547         Trace traceVol("RendererInServer::VolumeTools::Process " + std::to_string(oldAppliedVolume_) + "~" +
548             std::to_string(applyVolume));
549         AudioChannel channel = processConfig_.streamInfo.channels;
550         ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, oldAppliedVolume_, applyVolume);
551         int32_t volRet = VolumeTools::Process(desc, processConfig_.streamInfo.format, mapVols);
552         oldAppliedVolume_ = applyVolume;
553         if (volRet != SUCCESS) {
554             AUDIO_WARNING_LOG("VolumeTools::Process error: %{public}d", volRet);
555         }
556     }
557 }
558 
WriteData()559 int32_t RendererInServer::WriteData()
560 {
561     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
562     uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
563     Trace trace1(traceTag_ + " WriteData"); // RendererInServer::sessionid:100001 WriteData
564     if (currentReadFrame + spanSizeInFrame_ > currentWriteFrame) {
565         Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
566         FutexTool::FutexWake(audioServerBuffer_->GetFutex());
567         if (!offloadEnable_) {
568             CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
569                 "invalid write and read position.");
570             uint64_t dataSize = currentWriteFrame - currentReadFrame;
571             AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
572                 streamIndex_, dataSize);
573         }
574         return ERR_OPERATION_FAILED;
575     }
576 
577     BufferDesc bufferDesc = {nullptr, 0, 0}; // will be changed in GetReadbuffer
578     if (audioServerBuffer_->GetReadbuffer(currentReadFrame, bufferDesc) == SUCCESS) {
579         if (bufferDesc.buffer == nullptr) {
580             AUDIO_ERR_LOG("The buffer is null!");
581             return ERR_INVALID_PARAM;
582         }
583         uint64_t durationMs = ((byteSizePerFrame_ * processConfig_.streamInfo.samplingRate) == 0) ? 0
584             : ((MSEC_PER_SEC * processConfig_.rendererInfo.expectedPlaybackDurationBytes) /
585             (byteSizePerFrame_ * processConfig_.streamInfo.samplingRate));
586         if (processConfig_.streamType != STREAM_ULTRASONIC && (GetFadeStrategy(durationMs) == FADE_STRATEGY_DEFAULT)) {
587             if (currentReadFrame + spanSizeInFrame_ == currentWriteFrame) {
588                 DoFadingOut(bufferDesc);
589             }
590         }
591         stream_->EnqueueBuffer(bufferDesc);
592         if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
593             DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
594             AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
595                 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
596         }
597 
598         OtherStreamEnqueue(bufferDesc);
599 
600         WriteMuteDataSysEvent(bufferDesc);
601         memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength); // clear is needed for reuse.
602         // Client may write the buffer immediately after SetCurReadFrame, so put memset_s before it!
603         uint64_t nextReadFrame = currentReadFrame + spanSizeInFrame_;
604         audioServerBuffer_->SetCurReadFrame(nextReadFrame);
605     }
606     FutexTool::FutexWake(audioServerBuffer_->GetFutex());
607     standByCounter_ = 0;
608     lastWriteTime_ = ClockTime::GetCurNano();
609     return SUCCESS;
610 }
611 
OtherStreamEnqueue(const BufferDesc & bufferDesc)612 void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc)
613 {
614     // for inner capture
615     for (auto &capInfo : captureInfos_) {
616         InnerCaptureOtherStream(bufferDesc, capInfo.second);
617     }
618     // for dual tone
619     if (isDualToneEnabled_) {
620         Trace traceDup("RendererInServer::WriteData DualToneSteam write");
621         std::lock_guard<std::mutex> lock(dualToneMutex_);
622         if (dualToneStream_ != nullptr) {
623             dualToneStream_->EnqueueBuffer(bufferDesc); // what if enqueue fail?
624         }
625     }
626 }
627 
InnerCaptureOtherStream(const BufferDesc & bufferDesc,CaptureInfo & captureInfo)628 void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo)
629 {
630     if (captureInfo.isInnerCapEnabled) {
631         Trace traceDup("RendererInServer::WriteData DupSteam write");
632         std::lock_guard<std::mutex> lock(dupMutex_);
633         if (captureInfo.dupStream != nullptr) {
634             if (renderEmptyCountForInnerCap_ > 0) {
635                 size_t emptyBufferSize = static_cast<size_t>(renderEmptyCountForInnerCap_) * spanSizeInByte_;
636                 auto buffer = std::make_unique<uint8_t []>(emptyBufferSize);
637                 BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize};
638                 memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength);
639                 captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc);
640                 renderEmptyCountForInnerCap_ = 0;
641             }
642             captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail?
643         }
644     }
645 }
646 
WriteEmptyData()647 void RendererInServer::WriteEmptyData()
648 {
649     Trace trace("RendererInServer::WriteEmptyData");
650     AUDIO_WARNING_LOG("Underrun, write empty data");
651     BufferDesc bufferDesc = stream_->DequeueBuffer(spanSizeInByte_);
652     memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
653     stream_->EnqueueBuffer(bufferDesc);
654     return;
655 }
656 
OnWriteData(size_t length)657 int32_t RendererInServer::OnWriteData(size_t length)
658 {
659     Trace trace("RendererInServer::OnWriteData length " + std::to_string(length));
660     bool mayNeedForceWrite = false;
661     if (writeLock_.try_lock()) {
662         // length unit is bytes, using spanSizeInByte_
663         for (size_t i = 0; i < length / spanSizeInByte_; i++) {
664             mayNeedForceWrite = WriteData() != SUCCESS || mayNeedForceWrite;
665         }
666         writeLock_.unlock();
667     } else {
668         mayNeedForceWrite = true;
669     }
670 
671     size_t maxEmptyCount = 1;
672     size_t writableSize = stream_->GetWritableSize();
673     if (mayNeedForceWrite && writableSize >= spanSizeInByte_ * maxEmptyCount) {
674         AUDIO_DEBUG_LOG("Server need force write to recycle callback");
675         needForceWrite_ =
676             writableSize / spanSizeInByte_ > 3 ? 0 : 3 - writableSize / spanSizeInByte_; // 3 is maxlength - 1
677     }
678 
679     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
680     audioServerBuffer_->SetHandleInfo(currentReadFrame, ClockTime::GetCurNano() + MOCK_LATENCY);
681 
682     if (mayNeedForceWrite) {
683         return ERR_RENDERER_IN_SERVER_UNDERRUN;
684     }
685 
686     return SUCCESS;
687 }
688 
689 // Call WriteData will hold mainloop lock in EnqueueBuffer, we should not lock a mutex in WriteData while OnWriteData is
690 // called with mainloop locking.
UpdateWriteIndex()691 int32_t RendererInServer::UpdateWriteIndex()
692 {
693     Trace trace("RendererInServer::UpdateWriteIndex needForceWrite" + std::to_string(needForceWrite_));
694     if (managerType_ != PLAYBACK) {
695         IStreamManager::GetPlaybackManager(managerType_).TriggerStartIfNecessary();
696     }
697     if (needForceWrite_ < 3 && stream_->GetWritableSize() >= spanSizeInByte_) { // 3 is maxlength - 1
698         if (writeLock_.try_lock()) {
699             AUDIO_DEBUG_LOG("Start force write data");
700             int32_t ret = WriteData();
701             if (ret == SUCCESS) {
702                 needForceWrite_++;
703             }
704             writeLock_.unlock();
705         }
706     }
707 
708     if (afterDrain == true) {
709         if (writeLock_.try_lock()) {
710             afterDrain = false;
711             AUDIO_DEBUG_LOG("After drain, start write data");
712             WriteData();
713             writeLock_.unlock();
714         }
715     }
716     return SUCCESS;
717 }
718 
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)719 int32_t RendererInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
720 {
721     buffer = audioServerBuffer_;
722     return SUCCESS;
723 }
724 
GetSessionId(uint32_t & sessionId)725 int32_t RendererInServer::GetSessionId(uint32_t &sessionId)
726 {
727     CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
728     sessionId = streamIndex_;
729     CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
730         sessionId);
731 
732     return SUCCESS;
733 }
734 
Start()735 int32_t RendererInServer::Start()
736 {
737     int32_t ret = StartInner();
738     RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
739     if (playerDfx_) {
740         playerDfx_->WriteDfxStartMsg(streamIndex_, stage, sourceDuration_, processConfig_);
741     }
742     return ret;
743 }
744 
StartInner()745 int32_t RendererInServer::StartInner()
746 {
747     AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_);
748     if (standByEnable_) {
749         AUDIO_INFO_LOG("sessionId: %{public}u call to exit stand by!", streamIndex_);
750         CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
751             ERR_OPERATION_FAILED, "stream status is nullptr");
752         standByCounter_ = 0;
753         startedTime_ = ClockTime::GetCurNano();
754         audioServerBuffer_->GetStreamStatus()->store(STREAM_STARTING);
755         int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
756             IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
757         return ret;
758     }
759     needForceWrite_ = 0;
760     std::unique_lock<std::mutex> lock(statusLock_);
761     if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
762         AUDIO_ERR_LOG("RendererInServer::Start failed, Illegal state: %{public}u", status_);
763         return ERR_ILLEGAL_STATE;
764     }
765     status_ = I_STATUS_STARTING;
766     {
767         std::lock_guard<std::mutex> lock(fadeoutLock_);
768         AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
769         fadeoutFlag_ = NO_FADING;
770     }
771     int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
772         IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
773     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
774 
775     startedTime_ = ClockTime::GetCurNano();
776     uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
777     int64_t tempTime = ClockTime::GetCurNano() + MOCK_LATENCY;
778     audioServerBuffer_->SetHandleInfo(currentReadFrame, tempTime);
779     AUDIO_INFO_LOG("Server update position %{public}" PRIu64" time%{public} " PRId64".", currentReadFrame, tempTime);
780     resetTime_ = true;
781 
782     {
783         std::lock_guard<std::mutex> lock(dupMutex_);
784         for (auto &capInfo : captureInfos_) {
785             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
786                 capInfo.second.dupStream->Start();
787             }
788         }
789     }
790     enterStandbyTime_ = 0;
791 
792     dualToneStreamInStart();
793     AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(streamIndex_);
794     return SUCCESS;
795 }
796 
dualToneStreamInStart()797 void RendererInServer::dualToneStreamInStart()
798 {
799     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
800         //Joint judgment ensures that there is a double ring and there is a stream to enter.
801         stream_->GetAudioEffectMode(effectModeWhenDual_);
802         stream_->SetAudioEffectMode(EFFECT_NONE);
803         std::lock_guard<std::mutex> lock(dualToneMutex_);
804         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
805         if (dualToneStream_ != nullptr) {
806             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
807             //modified elsewhere, it was decided again after the lock was awarded.
808             dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
809             dualToneStream_->Start();
810         }
811     }
812 }
813 
Pause()814 int32_t RendererInServer::Pause()
815 {
816     AUDIO_INFO_LOG("Pause.");
817     std::unique_lock<std::mutex> lock(statusLock_);
818     if (status_ != I_STATUS_STARTED) {
819         AUDIO_ERR_LOG("RendererInServer::Pause failed, Illegal state: %{public}u", status_);
820         return ERR_ILLEGAL_STATE;
821     }
822     status_ = I_STATUS_PAUSING;
823     if (standByEnable_) {
824         AUDIO_INFO_LOG("sessionId: %{public}u call Pause while stand by", streamIndex_);
825         CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
826             ERR_OPERATION_FAILED, "stream status is nullptr");
827         standByEnable_ = false;
828         enterStandbyTime_ = 0;
829         audioServerBuffer_->GetStreamStatus()->store(STREAM_PAUSED);
830         if (playerDfx_) {
831             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
832         }
833     }
834     standByCounter_ = 0;
835     int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
836         IStreamManager::GetPlaybackManager(managerType_).PauseRender(streamIndex_) : stream_->Pause();
837     {
838         std::lock_guard<std::mutex> lock(dupMutex_);
839         for (auto &capInfo : captureInfos_) {
840             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
841                 capInfo.second.dupStream->Pause();
842             }
843         }
844     }
845     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
846         //Joint judgment ensures that there is a double ring and there is a stream to enter.
847         stream_->SetAudioEffectMode(effectModeWhenDual_);
848         std::lock_guard<std::mutex> lock(dualToneMutex_);
849         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
850         if (dualToneStream_ != nullptr) {
851             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
852             //modified elsewhere, it was decided again after the lock was awarded.
853             dualToneStream_->Pause();
854             dualToneStream_->SetAudioEffectMode(effectModeWhenDual_);
855         }
856     }
857     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
858 
859     return SUCCESS;
860 }
861 
Flush()862 int32_t RendererInServer::Flush()
863 {
864     AUDIO_PRERELEASE_LOGI("Flush.");
865     Trace trace(traceTag_ + " Flush");
866     std::unique_lock<std::mutex> lock(statusLock_);
867     if (status_ == I_STATUS_STARTED) {
868         status_ = I_STATUS_FLUSHING_WHEN_STARTED;
869     } else if (status_ == I_STATUS_PAUSED) {
870         status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
871     } else if (status_ == I_STATUS_STOPPED) {
872         status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
873     } else {
874         AUDIO_ERR_LOG("RendererInServer::Flush failed, Illegal state: %{public}u", status_);
875         return ERR_ILLEGAL_STATE;
876     }
877 
878     // Flush buffer of audio server
879     uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
880     uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
881 
882     while (readFrame < writeFrame) {
883         BufferDesc bufferDesc = {nullptr, 0, 0};
884         int32_t readResult = audioServerBuffer_->GetReadbuffer(readFrame, bufferDesc);
885         if (readResult != 0) {
886             return ERR_OPERATION_FAILED;
887         }
888         memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
889         readFrame += spanSizeInFrame_;
890         AUDIO_INFO_LOG("On flush, read frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
891             "writeFrame: %{public}" PRIu64 "", readFrame, spanSizeInFrame_, writeFrame);
892         audioServerBuffer_->SetCurReadFrame(readFrame);
893     }
894 
895     int ret = stream_->Flush();
896     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
897     {
898         std::lock_guard<std::mutex> lock(dupMutex_);
899         for (auto &capInfo : captureInfos_) {
900             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
901                 capInfo.second.dupStream->Flush();
902             }
903         }
904     }
905     if (isDualToneEnabled_) {
906         std::lock_guard<std::mutex> lock(dualToneMutex_);
907         if (dualToneStream_ != nullptr) {
908             dualToneStream_->Flush();
909         }
910     }
911     return SUCCESS;
912 }
913 
DrainAudioBuffer()914 int32_t RendererInServer::DrainAudioBuffer()
915 {
916     return SUCCESS;
917 }
918 
Drain(bool stopFlag)919 int32_t RendererInServer::Drain(bool stopFlag)
920 {
921     {
922         std::unique_lock<std::mutex> lock(statusLock_);
923         if (status_ != I_STATUS_STARTED) {
924             AUDIO_ERR_LOG("RendererInServer::Drain failed, Illegal state: %{public}u", status_);
925             return ERR_ILLEGAL_STATE;
926         }
927         status_ = I_STATUS_DRAINING;
928     }
929     AUDIO_INFO_LOG("Start drain. stopFlag:%{public}d", stopFlag);
930     if (stopFlag) {
931         std::lock_guard<std::mutex> lock(fadeoutLock_);
932         AUDIO_INFO_LOG("fadeoutFlag_ = DO_FADINGOUT");
933         fadeoutFlag_ = DO_FADINGOUT;
934     }
935     DrainAudioBuffer();
936     AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(streamIndex_);
937     int ret = stream_->Drain(stopFlag);
938     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Drain stream failed, reason: %{public}d", ret);
939     {
940         std::lock_guard<std::mutex> lock(dupMutex_);
941         for (auto &capInfo : captureInfos_) {
942             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
943                 capInfo.second.dupStream->Drain(stopFlag);
944             }
945         }
946     }
947     if (isDualToneEnabled_) {
948         std::lock_guard<std::mutex> lock(dualToneMutex_);
949         if (dualToneStream_ != nullptr) {
950             dualToneStream_->Drain(stopFlag);
951         }
952     }
953     return SUCCESS;
954 }
955 
Stop()956 int32_t RendererInServer::Stop()
957 {
958     AUDIO_INFO_LOG("Stop.");
959     {
960         std::unique_lock<std::mutex> lock(statusLock_);
961         if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED && status_ != I_STATUS_DRAINING &&
962             status_ != I_STATUS_STARTING) {
963             AUDIO_ERR_LOG("RendererInServer::Stop failed, Illegal state: %{public}u", status_);
964             return ERR_ILLEGAL_STATE;
965         }
966         status_ = I_STATUS_STOPPING;
967     }
968     if (standByEnable_) {
969         AUDIO_INFO_LOG("sessionId: %{public}u call Stop while stand by", streamIndex_);
970         CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
971             ERR_OPERATION_FAILED, "stream status is nullptr");
972         standByEnable_ = false;
973         enterStandbyTime_ = 0;
974         audioServerBuffer_->GetStreamStatus()->store(STREAM_STOPPED);
975         if (playerDfx_) {
976             playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
977         }
978     }
979     {
980         std::lock_guard<std::mutex> lock(fadeoutLock_);
981         AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
982         fadeoutFlag_ = NO_FADING;
983     }
984     int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
985         IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop();
986     {
987         std::lock_guard<std::mutex> lock(dupMutex_);
988         for (auto &capInfo : captureInfos_) {
989             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
990                 capInfo.second.dupStream->Stop();
991             }
992         }
993     }
994     if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
995         //Joint judgment ensures that there is a double ring and there is a stream to enter.
996         stream_->SetAudioEffectMode(effectModeWhenDual_);
997         std::lock_guard<std::mutex> lock(dualToneMutex_);
998         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
999         if (dualToneStream_ != nullptr) {
1000             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1001             //modified elsewhere, it was decided again after the lock was awarded.
1002             dualToneStream_->Stop();
1003             dualToneStream_->SetAudioEffectMode(effectModeWhenDual_);
1004         }
1005     }
1006     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
1007     return SUCCESS;
1008 }
1009 
Release()1010 int32_t RendererInServer::Release()
1011 {
1012     AUDIO_INFO_LOG("Start release");
1013     AudioXCollie audioXCollie(
1014         "RendererInServer::Release", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1015             AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1016     {
1017         std::unique_lock<std::mutex> lock(statusLock_);
1018         if (status_ == I_STATUS_RELEASED) {
1019             AUDIO_INFO_LOG("Already released");
1020             return SUCCESS;
1021         }
1022     }
1023 
1024     if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1025         AudioService::GetInstance()->SetDecMaxRendererStreamCnt();
1026         AudioService::GetInstance()->CleanAppUseNumMap(processConfig_.appInfo.appUid);
1027     }
1028 
1029     int32_t ret = IStreamManager::GetPlaybackManager(managerType_).ReleaseRender(streamIndex_);
1030     AudioVolume::GetInstance()->RemoveStreamVolume(streamIndex_);
1031     AudioService::GetInstance()->RemoveRenderer(streamIndex_);
1032     if (ret < 0) {
1033         AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
1034         status_ = I_STATUS_INVALID;
1035         return ret;
1036     }
1037     status_ = I_STATUS_RELEASED;
1038     {
1039         std::lock_guard<std::mutex> lock(dupMutex_);
1040         for (auto &capInfo : captureInfos_) {
1041             if (capInfo.second.isInnerCapEnabled) {
1042                 DisableInnerCap(capInfo.first);
1043             }
1044         }
1045         captureInfos_.clear();
1046     }
1047     if (isDualToneEnabled_) {
1048         DisableDualTone();
1049     }
1050     return SUCCESS;
1051 }
1052 
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)1053 int32_t RendererInServer::GetAudioTime(uint64_t &framePos, uint64_t &timestamp)
1054 {
1055     if (status_ == I_STATUS_STOPPED) {
1056         AUDIO_WARNING_LOG("Current status is stopped");
1057         return ERR_ILLEGAL_STATE;
1058     }
1059     stream_->GetStreamFramesWritten(framePos);
1060     stream_->GetCurrentTimeStamp(timestamp);
1061     if (resetTime_) {
1062         resetTime_ = false;
1063         resetTimestamp_ = timestamp;
1064     }
1065     return SUCCESS;
1066 }
1067 
GetAudioPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency)1068 int32_t RendererInServer::GetAudioPosition(uint64_t &framePos, uint64_t &timestamp, uint64_t &latency)
1069 {
1070     if (status_ == I_STATUS_STOPPED) {
1071         AUDIO_PRERELEASE_LOGW("Current status is stopped");
1072         return ERR_ILLEGAL_STATE;
1073     }
1074     stream_->GetCurrentPosition(framePos, timestamp, latency);
1075     return SUCCESS;
1076 }
1077 
GetLatency(uint64_t & latency)1078 int32_t RendererInServer::GetLatency(uint64_t &latency)
1079 {
1080     std::unique_lock<std::mutex> lock(statusLock_);
1081     if (managerType_ == DIRECT_PLAYBACK) {
1082         latency = IStreamManager::GetPlaybackManager(managerType_).GetLatency();
1083         return SUCCESS;
1084     }
1085     return stream_->GetLatency(latency);
1086 }
1087 
SetRate(int32_t rate)1088 int32_t RendererInServer::SetRate(int32_t rate)
1089 {
1090     return stream_->SetRate(rate);
1091 }
1092 
SetLowPowerVolume(float volume)1093 int32_t RendererInServer::SetLowPowerVolume(float volume)
1094 {
1095     if (volume < MIN_FLOAT_VOLUME || volume > MAX_FLOAT_VOLUME) {
1096         AUDIO_ERR_LOG("invalid volume:%{public}f", volume);
1097         return ERR_INVALID_PARAM;
1098     }
1099     lowPowerVolume_ = volume;
1100     AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(streamIndex_, volume);
1101     for (auto &capInfo : captureInfos_) {
1102         if (capInfo.second.isInnerCapEnabled) {
1103             AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(
1104                 capInfo.second.dupStream->GetStreamIndex(), volume);
1105         }
1106     }
1107     if (isDualToneEnabled_) {
1108         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, volume);
1109     }
1110     if (offloadEnable_) {
1111         OffloadSetVolumeInner();
1112     }
1113     return SUCCESS;
1114 }
1115 
GetLowPowerVolume(float & volume)1116 int32_t RendererInServer::GetLowPowerVolume(float &volume)
1117 {
1118     volume = lowPowerVolume_;
1119     return SUCCESS;
1120 }
1121 
SetAudioEffectMode(int32_t effectMode)1122 int32_t RendererInServer::SetAudioEffectMode(int32_t effectMode)
1123 {
1124     if (isDualToneEnabled_) {
1125         effectModeWhenDual_ = effectMode;
1126         return SUCCESS;
1127     }
1128     return stream_->SetAudioEffectMode(effectMode);
1129 }
1130 
GetAudioEffectMode(int32_t & effectMode)1131 int32_t RendererInServer::GetAudioEffectMode(int32_t &effectMode)
1132 {
1133     return stream_->GetAudioEffectMode(effectMode);
1134 }
1135 
SetPrivacyType(int32_t privacyType)1136 int32_t RendererInServer::SetPrivacyType(int32_t privacyType)
1137 {
1138     return stream_->SetPrivacyType(privacyType);
1139 }
1140 
GetPrivacyType(int32_t & privacyType)1141 int32_t RendererInServer::GetPrivacyType(int32_t &privacyType)
1142 {
1143     return stream_->GetPrivacyType(privacyType);
1144 }
1145 
EnableInnerCap(int32_t innerCapId)1146 int32_t RendererInServer::EnableInnerCap(int32_t innerCapId)
1147 {
1148     // in plan
1149     if (captureInfos_.count(innerCapId) && captureInfos_[innerCapId].isInnerCapEnabled) {
1150         AUDIO_INFO_LOG("InnerCap is already enabled,id:%{public}d", innerCapId);
1151         return SUCCESS;
1152     }
1153     int32_t ret = InitDupStream(innerCapId);
1154     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dup stream failed");
1155     return SUCCESS;
1156 }
1157 
DisableInnerCap(int32_t innerCapId)1158 int32_t RendererInServer::DisableInnerCap(int32_t innerCapId)
1159 {
1160     if (!captureInfos_.count(innerCapId) || !captureInfos_[innerCapId].isInnerCapEnabled) {
1161         AUDIO_WARNING_LOG("InnerCap is already disabled.capId:%{public}d", innerCapId);
1162         return ERR_INVALID_OPERATION;
1163     }
1164     captureInfos_[innerCapId].isInnerCapEnabled = false;
1165     AUDIO_INFO_LOG("Disable dup renderer %{public}u with status: %{public}d", streamIndex_, status_);
1166     // in plan: call stop?
1167     if (captureInfos_[innerCapId].dupStream != nullptr) {
1168         uint32_t dupStreamIndex = captureInfos_[innerCapId].dupStream->GetStreamIndex();
1169         IStreamManager::GetDupPlaybackManager().ReleaseRender(dupStreamIndex);
1170         AudioVolume::GetInstance()->RemoveStreamVolume(dupStreamIndex);
1171         captureInfos_[innerCapId].dupStream = nullptr;
1172     }
1173     return SUCCESS;
1174 }
1175 
InitDupStream(int32_t innerCapId)1176 int32_t RendererInServer::InitDupStream(int32_t innerCapId)
1177 {
1178     std::lock_guard<std::mutex> lock(dupMutex_);
1179     auto &capInfo = captureInfos_[innerCapId];
1180     AudioProcessConfig dupConfig = processConfig_;
1181     dupConfig.innerCapId = innerCapId;
1182     int32_t ret = IStreamManager::GetDupPlaybackManager().CreateRender(dupConfig, capInfo.dupStream);
1183     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && capInfo.dupStream != nullptr,
1184         ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1185     uint32_t dupStreamIndex = capInfo.dupStream->GetStreamIndex();
1186     bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1187     AudioVolume::GetInstance()->AddStreamVolume(dupStreamIndex, processConfig_.streamType,
1188         processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1189         isSystemApp, processConfig_.rendererInfo.volumeMode);
1190 
1191     dupStreamCallback_ = std::make_shared<StreamCallbacks>(dupStreamIndex);
1192     capInfo.dupStream->RegisterStatusCallback(dupStreamCallback_);
1193     capInfo.dupStream->RegisterWriteCallback(dupStreamCallback_);
1194 
1195     AUDIO_INFO_LOG("Dup Renderer %{public}u with status: %{public}d", streamIndex_, status_);
1196     capInfo.isInnerCapEnabled = true;
1197 
1198     if (audioServerBuffer_ != nullptr) {
1199         float clientVolume = audioServerBuffer_->GetStreamVolume();
1200         float duckFactor = audioServerBuffer_->GetDuckFactor();
1201         bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1202         // If some factors are not needed, remove them.
1203         AudioVolume::GetInstance()->SetStreamVolume(dupStreamIndex, clientVolume);
1204         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dupStreamIndex, duckFactor);
1205         AudioVolume::GetInstance()->SetStreamVolumeMute(dupStreamIndex, isMuted);
1206         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dupStreamIndex, lowPowerVolume_);
1207     }
1208     if (status_ == I_STATUS_STARTED) {
1209         AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dup stream", streamIndex_);
1210         capInfo.dupStream->Start();
1211 
1212         if (offloadEnable_) {
1213             renderEmptyCountForInnerCap_ = OFFLOAD_INNER_CAP_PREBUF;
1214         }
1215     }
1216     return SUCCESS;
1217 }
1218 
EnableDualTone()1219 int32_t RendererInServer::EnableDualTone()
1220 {
1221     if (isDualToneEnabled_) {
1222         AUDIO_INFO_LOG("DualTone is already enabled");
1223         return SUCCESS;
1224     }
1225     int32_t ret = InitDualToneStream();
1226     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dual tone stream failed");
1227     return SUCCESS;
1228 }
1229 
DisableDualTone()1230 int32_t RendererInServer::DisableDualTone()
1231 {
1232     std::lock_guard<std::mutex> lock(dualToneMutex_);
1233     if (!isDualToneEnabled_) {
1234         AUDIO_WARNING_LOG("DualTone is already disabled.");
1235         return ERR_INVALID_OPERATION;
1236     }
1237     isDualToneEnabled_ = false;
1238     AUDIO_INFO_LOG("Disable dual tone renderer:[%{public}u] with status: %{public}d", dualToneStreamIndex_, status_);
1239     IStreamManager::GetDualPlaybackManager().ReleaseRender(dualToneStreamIndex_);
1240     AudioVolume::GetInstance()->RemoveStreamVolume(dualToneStreamIndex_);
1241     dualToneStream_ = nullptr;
1242 
1243     return ERROR;
1244 }
1245 
InitDualToneStream()1246 int32_t RendererInServer::InitDualToneStream()
1247 {
1248     {
1249         std::lock_guard<std::mutex> lock(dualToneMutex_);
1250 
1251         int32_t ret = IStreamManager::GetDualPlaybackManager().CreateRender(processConfig_, dualToneStream_);
1252         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && dualToneStream_ != nullptr,
1253             ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1254         dualToneStreamIndex_ = dualToneStream_->GetStreamIndex();
1255         AUDIO_INFO_LOG("init dual tone renderer:[%{public}u]", dualToneStreamIndex_);
1256         bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1257         AudioVolume::GetInstance()->AddStreamVolume(dualToneStreamIndex_, processConfig_.streamType,
1258             processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1259             isSystemApp, processConfig_.rendererInfo.volumeMode);
1260 
1261         isDualToneEnabled_ = true;
1262     }
1263 
1264     if (audioServerBuffer_ != nullptr) {
1265         float clientVolume = audioServerBuffer_->GetStreamVolume();
1266         float duckFactor = audioServerBuffer_->GetDuckFactor();
1267         bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1268         // If some factors are not needed, remove them.
1269         AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1270         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1271         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1272         AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, lowPowerVolume_);
1273     }
1274     if (status_ == I_STATUS_STARTED) {
1275         AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dual stream", dualToneStreamIndex_);
1276         stream_->GetAudioEffectMode(effectModeWhenDual_);
1277         stream_->SetAudioEffectMode(EFFECT_NONE);
1278         std::lock_guard<std::mutex> lock(dualToneMutex_);
1279         //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1280         if (dualToneStream_ != nullptr) {
1281             //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1282             //modified elsewhere, it was decided again after the lock was awarded.
1283             dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1284             dualToneStream_->Start();
1285         }
1286     }
1287     return SUCCESS;
1288 }
1289 
StreamCallbacks(uint32_t streamIndex)1290 StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex)
1291 {
1292     AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_);
1293 }
1294 
OnStatusUpdate(IOperation operation)1295 void StreamCallbacks::OnStatusUpdate(IOperation operation)
1296 {
1297     AUDIO_INFO_LOG("DupStream %{public}u recv operation: %{public}d", streamIndex_, operation);
1298 }
1299 
OnWriteData(size_t length)1300 int32_t StreamCallbacks::OnWriteData(size_t length)
1301 {
1302     Trace trace("DupStream::OnWriteData length " + std::to_string(length));
1303     return SUCCESS;
1304 }
1305 
SetOffloadMode(int32_t state,bool isAppBack)1306 int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack)
1307 {
1308     int32_t ret = stream_->SetOffloadMode(state, isAppBack);
1309     {
1310         std::lock_guard<std::mutex> lock(dupMutex_);
1311         for (auto &capInfo : captureInfos_) {
1312             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1313                 capInfo.second.dupStream->UpdateMaxLength(350); // 350 for cover offload
1314             }
1315         }
1316     }
1317     if (isDualToneEnabled_) {
1318         std::lock_guard<std::mutex> lock(dualToneMutex_);
1319         if (dualToneStream_ != nullptr) {
1320             dualToneStream_->UpdateMaxLength(350); // 350 for cover offload
1321         }
1322     }
1323     return ret;
1324 }
1325 
UnsetOffloadMode()1326 int32_t RendererInServer::UnsetOffloadMode()
1327 {
1328     int32_t ret = stream_->UnsetOffloadMode();
1329     {
1330         std::lock_guard<std::mutex> lock(dupMutex_);
1331         for (auto &capInfo : captureInfos_) {
1332             if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1333                 capInfo.second.dupStream->UpdateMaxLength(20); // 20 for unset offload
1334             }
1335         }
1336     }
1337     if (isDualToneEnabled_) {
1338         std::lock_guard<std::mutex> lock(dualToneMutex_);
1339         if (dualToneStream_ != nullptr) {
1340             dualToneStream_->UpdateMaxLength(20); // 20 for cover offload
1341         }
1342     }
1343     return ret;
1344 }
1345 
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)1346 int32_t RendererInServer::GetOffloadApproximatelyCacheTime(uint64_t &timestamp, uint64_t &paWriteIndex,
1347     uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
1348 {
1349     return stream_->GetOffloadApproximatelyCacheTime(timestamp, paWriteIndex, cacheTimeDsp, cacheTimePa);
1350 }
1351 
OffloadSetVolumeInner()1352 int32_t RendererInServer::OffloadSetVolumeInner()
1353 {
1354     AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(processConfig_.streamType);
1355     float volume = AudioVolume::GetInstance()->GetVolume(streamIndex_, volumeType, "offload");
1356     AUDIO_INFO_LOG("sessionID %{public}u [volumeType:%{public}d volume: %{public}f]",
1357         streamIndex_, volumeType, volume);
1358     float volumeHistory = AudioVolume::GetInstance()->GetHistoryVolume(streamIndex_);
1359     if (!IsVolumeSame(volumeHistory, volume, AUDIO_VOLOMUE_EPSILON)) {
1360         AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, volume);
1361         AudioVolume::GetInstance()->Monitor(streamIndex_, true);
1362     }
1363     return stream_->OffloadSetVolume(volume);
1364 }
1365 
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)1366 int32_t RendererInServer::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
1367 {
1368     return stream_->UpdateSpatializationState(spatializationEnabled, headTrackingEnabled);
1369 }
1370 
GetStreamManagerType() const1371 int32_t RendererInServer::GetStreamManagerType() const noexcept
1372 {
1373     return managerType_ == DIRECT_PLAYBACK ? AUDIO_DIRECT_MANAGER_TYPE : AUDIO_NORMAL_MANAGER_TYPE;
1374 }
1375 
IsHighResolution() const1376 bool RendererInServer::IsHighResolution() const noexcept
1377 {
1378     Trace trace("CheckHighResolution");
1379     if (processConfig_.deviceType != DEVICE_TYPE_WIRED_HEADSET &&
1380         processConfig_.deviceType != DEVICE_TYPE_USB_HEADSET) {
1381         AUDIO_INFO_LOG("normal stream,device type:%{public}d", processConfig_.deviceType);
1382         return false;
1383     }
1384     if (processConfig_.streamType != STREAM_MUSIC || processConfig_.streamInfo.samplingRate < SAMPLE_RATE_48000 ||
1385         processConfig_.streamInfo.format < SAMPLE_S24LE ||
1386         processConfig_.rendererInfo.pipeType != PIPE_TYPE_DIRECT_MUSIC) {
1387         AUDIO_INFO_LOG("normal stream because stream info");
1388         return false;
1389     }
1390     if (processConfig_.streamInfo.samplingRate > SAMPLE_RATE_192000) {
1391         AUDIO_INFO_LOG("sample rate over 192k");
1392         return false;
1393     }
1394     if (IStreamManager::GetPlaybackManager(DIRECT_PLAYBACK).GetStreamCount() > 0) {
1395         AUDIO_INFO_LOG("high resolution exist.");
1396         return false;
1397     }
1398     return true;
1399 }
1400 
SetSilentModeAndMixWithOthers(bool on)1401 int32_t RendererInServer::SetSilentModeAndMixWithOthers(bool on)
1402 {
1403     silentModeAndMixWithOthers_ = on;
1404     AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", on);
1405     bool isMuted = (isMuted_ || on || muteFlag_);
1406     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1407     for (auto &capInfo : captureInfos_) {
1408         if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1409             AudioVolume::GetInstance()->SetStreamVolumeMute(
1410                 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1411         }
1412     }
1413     if (isDualToneEnabled_) {
1414         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1415     }
1416     if (offloadEnable_) {
1417         OffloadSetVolumeInner();
1418     }
1419     return SUCCESS;
1420 }
1421 
SetClientVolume()1422 int32_t RendererInServer::SetClientVolume()
1423 {
1424     if (audioServerBuffer_ == nullptr || playerDfx_ == nullptr) {
1425         AUDIO_WARNING_LOG("buffer in not inited");
1426         return ERROR;
1427     }
1428     float clientVolume = audioServerBuffer_->GetStreamVolume();
1429     int32_t ret = stream_->SetClientVolume(clientVolume);
1430     SetStreamVolumeInfoForEnhanceChain();
1431     AudioVolume::GetInstance()->SetStreamVolume(streamIndex_, clientVolume);
1432     for (auto &capInfo : captureInfos_) {
1433         if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1434             AudioVolume::GetInstance()->SetStreamVolume(
1435                 capInfo.second.dupStream->GetStreamIndex(), clientVolume);
1436         }
1437     }
1438     if (isDualToneEnabled_) {
1439         AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1440     }
1441     if (offloadEnable_) {
1442         OffloadSetVolumeInner();
1443     }
1444 
1445     RendererStage stage = clientVolume == 0 ? RENDERER_STAGE_SET_VOLUME_ZERO : RENDERER_STAGE_SET_VOLUME_NONZERO;
1446     playerDfx_->WriteDfxActionMsg(streamIndex_, stage);
1447     return ret;
1448 }
1449 
SetMute(bool isMute)1450 int32_t RendererInServer::SetMute(bool isMute)
1451 {
1452     isMuted_ = isMute;
1453     AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", isMute);
1454     bool isMuted = (isMute || silentModeAndMixWithOthers_ || muteFlag_);
1455     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1456     for (auto &capInfo : captureInfos_) {
1457         if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1458             AudioVolume::GetInstance()->SetStreamVolumeMute(
1459                 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1460         }
1461     }
1462     if (isDualToneEnabled_) {
1463         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1464     }
1465     if (offloadEnable_) {
1466         OffloadSetVolumeInner();
1467     }
1468     return SUCCESS;
1469 }
1470 
SetDuckFactor(float duckFactor)1471 int32_t RendererInServer::SetDuckFactor(float duckFactor)
1472 {
1473     if (duckFactor < MIN_FLOAT_VOLUME || duckFactor > MAX_FLOAT_VOLUME) {
1474         AUDIO_ERR_LOG("invalid duck volume:%{public}f", duckFactor);
1475         return ERR_INVALID_PARAM;
1476     }
1477     AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(streamIndex_, duckFactor);
1478     for (auto &capInfo : captureInfos_) {
1479         if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1480             AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(
1481                 capInfo.second.dupStream->GetStreamIndex(), duckFactor);
1482         }
1483     }
1484     if (isDualToneEnabled_) {
1485         AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1486     }
1487     if (offloadEnable_) {
1488         OffloadSetVolumeInner();
1489     }
1490     return SUCCESS;
1491 }
1492 
SetStreamVolumeInfoForEnhanceChain()1493 int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain()
1494 {
1495     uint32_t sessionId = streamIndex_;
1496     float streamVolume = audioServerBuffer_->GetStreamVolume();
1497     AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
1498     CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr");
1499     int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume);
1500     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed");
1501     return ret;
1502 }
1503 
OnDataLinkConnectionUpdate(IOperation operation)1504 void RendererInServer::OnDataLinkConnectionUpdate(IOperation operation)
1505 {
1506     std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
1507     CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr");
1508     switch (operation) {
1509         case OPERATION_DATA_LINK_CONNECTING:
1510             AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTING received");
1511             stateListener->OnOperationHandled(DATA_LINK_CONNECTING, 0);
1512             break;
1513         case OPERATION_DATA_LINK_CONNECTED:
1514             AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTED received");
1515             stateListener->OnOperationHandled(DATA_LINK_CONNECTED, 0);
1516             break;
1517         default:
1518             return;
1519     }
1520 }
1521 
GetActualStreamManagerType() const1522 int32_t RendererInServer::GetActualStreamManagerType() const noexcept
1523 {
1524     return managerType_;
1525 }
1526 
GetStatusStr(IStatus status)1527 static std::string GetStatusStr(IStatus status)
1528 {
1529     switch (status) {
1530         case I_STATUS_INVALID:
1531             return "INVALID";
1532         case I_STATUS_IDLE:
1533             return "IDEL";
1534         case I_STATUS_STARTING:
1535             return "STARTING";
1536         case I_STATUS_STARTED:
1537             return "STARTED";
1538         case I_STATUS_PAUSING:
1539             return "PAUSING";
1540         case I_STATUS_PAUSED:
1541             return "PAUSED";
1542         case I_STATUS_FLUSHING_WHEN_STARTED:
1543             return "FLUSHING_WHEN_STARTED";
1544         case I_STATUS_FLUSHING_WHEN_PAUSED:
1545             return "FLUSHING_WHEN_PAUSED";
1546         case I_STATUS_FLUSHING_WHEN_STOPPED:
1547             return "FLUSHING_WHEN_STOPPED";
1548         case I_STATUS_DRAINING:
1549             return "DRAINING";
1550         case I_STATUS_DRAINED:
1551             return "DRAINED";
1552         case I_STATUS_STOPPING:
1553             return "STOPPING";
1554         case I_STATUS_STOPPED:
1555             return "STOPPED";
1556         case I_STATUS_RELEASING:
1557             return "RELEASING";
1558         case I_STATUS_RELEASED:
1559             return "RELEASED";
1560         default:
1561             break;
1562     }
1563     return "NO_SUCH_STATUS";
1564 }
1565 
GetManagerTypeStr(ManagerType type)1566 static std::string GetManagerTypeStr(ManagerType type)
1567 {
1568     switch (type) {
1569         case PLAYBACK:
1570             return "Normal";
1571         case DUP_PLAYBACK:
1572             return "Dup Playback";
1573         case DUAL_PLAYBACK:
1574             return "DUAL Playback";
1575         case DIRECT_PLAYBACK:
1576             return "Direct";
1577         case VOIP_PLAYBACK:
1578             return "Voip";
1579         case RECORDER:
1580             return "Recorder";
1581         default:
1582             break;
1583     }
1584     return "NO_SUCH_TYPE";
1585 }
1586 
Dump(std::string & dumpString)1587 bool RendererInServer::Dump(std::string &dumpString)
1588 {
1589     if (managerType_ != DIRECT_PLAYBACK && managerType_ != VOIP_PLAYBACK) {
1590         return false;
1591     }
1592     // dump audio stream info
1593     dumpString += "audio stream info:\n";
1594     AppendFormat(dumpString, "  - session id:%u\n", streamIndex_);
1595     AppendFormat(dumpString, "  - appid:%d\n", processConfig_.appInfo.appPid);
1596     AppendFormat(dumpString, "  - stream type:%d\n", processConfig_.streamType);
1597 
1598     AppendFormat(dumpString, "  - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
1599     AppendFormat(dumpString, "  - channels: %u\n", processConfig_.streamInfo.channels);
1600     AppendFormat(dumpString, "  - format: %u\n", processConfig_.streamInfo.format);
1601     AppendFormat(dumpString, "  - device type: %u\n", processConfig_.deviceType);
1602     AppendFormat(dumpString, "  - sink type: %s\n", GetManagerTypeStr(managerType_).c_str());
1603 
1604     // dump status info
1605     AppendFormat(dumpString, "  - Current stream status: %s\n", GetStatusStr(status_).c_str());
1606     if (audioServerBuffer_ != nullptr) {
1607         AppendFormat(dumpString, "  - Current read position: %u\n", audioServerBuffer_->GetCurReadFrame());
1608         AppendFormat(dumpString, "  - Current write position: %u\n", audioServerBuffer_->GetCurWriteFrame());
1609     }
1610 
1611     dumpString += "\n";
1612     return true;
1613 }
1614 
SetNonInterruptMute(const bool muteFlag)1615 void RendererInServer::SetNonInterruptMute(const bool muteFlag)
1616 {
1617     AUDIO_INFO_LOG("mute flag %{public}d", muteFlag);
1618     muteFlag_ = muteFlag;
1619     AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
1620 
1621     bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag);
1622     AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1623     for (auto &captureInfo : captureInfos_) {
1624         if (captureInfo.second.isInnerCapEnabled && captureInfo.second.dupStream != nullptr) {
1625             AudioVolume::GetInstance()->SetStreamVolumeMute(
1626                 captureInfo.second.dupStream->GetStreamIndex(), isMuted);
1627         }
1628     }
1629     if (isDualToneEnabled_) {
1630         AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1631     }
1632     if (offloadEnable_) {
1633         OffloadSetVolumeInner();
1634     }
1635 }
1636 
RestoreSession(RestoreInfo restoreInfo)1637 RestoreStatus RendererInServer::RestoreSession(RestoreInfo restoreInfo)
1638 {
1639     RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
1640     if (restoreStatus == NEED_RESTORE) {
1641         audioServerBuffer_->SetRestoreInfo(restoreInfo);
1642     }
1643     return restoreStatus;
1644 }
1645 
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)1646 int32_t RendererInServer::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
1647 {
1648     return PolicyHandler::GetInstance().SetDefaultOutputDevice(defaultOutputDevice, streamIndex_,
1649         processConfig_.rendererInfo.streamUsage, status_ == I_STATUS_STARTED);
1650 }
1651 
SetSourceDuration(int64_t duration)1652 int32_t RendererInServer::SetSourceDuration(int64_t duration)
1653 {
1654     sourceDuration_ = duration;
1655     return SUCCESS;
1656 }
1657 
1658 } // namespace AudioStandard
1659 } // namespace OHOS
1660