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 ×tamp)
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 ×tamp, 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 ×tamp, 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