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