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 &timestamp)
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 &timestamp, 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 &timestamp, 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