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