• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "AudioProcessInServer"
17 #endif
18 
19 #include "audio_process_in_server.h"
20 #include "policy_handler.h"
21 
22 #include "securec.h"
23 
24 #include "audio_errors.h"
25 #include "audio_capturer_log.h"
26 #include "audio_service.h"
27 #include "audio_schedule.h"
28 #include "audio_utils.h"
29 #include "media_monitor_manager.h"
30 #include "audio_dump_pcm.h"
31 #include "audio_performance_monitor.h"
32 #ifdef RESSCHE_ENABLE
33 #include "res_type.h"
34 #include "res_sched_client.h"
35 #endif
36 
37 namespace OHOS {
38 namespace AudioStandard {
39 namespace {
40 static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
41 }
42 
Create(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)43 sptr<AudioProcessInServer> AudioProcessInServer::Create(const AudioProcessConfig &processConfig,
44     ProcessReleaseCallback *releaseCallback)
45 {
46     sptr<AudioProcessInServer> process = new(std::nothrow) AudioProcessInServer(processConfig, releaseCallback);
47 
48     return process;
49 }
50 
AudioProcessInServer(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)51 AudioProcessInServer::AudioProcessInServer(const AudioProcessConfig &processConfig,
52     ProcessReleaseCallback *releaseCallback) : processConfig_(processConfig), releaseCallback_(releaseCallback)
53 {
54     if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) {
55         sessionId_ = PolicyHandler::GetInstance().GenerateSessionId(processConfig_.appInfo.appUid);
56     } else {
57         sessionId_ = processConfig.originalSessionId;
58     }
59 
60     const auto [samplingRate, encoding, format, channels, channelLayout] = processConfig.streamInfo;
61     // eg: 100005_dump_process_server_audio_48000_2_1.pcm
62     dumpFileName_ = std::to_string(sessionId_) + '_' + "_dump_process_server_audio_" +
63         std::to_string(samplingRate) + '_' + std::to_string(channels) + '_' + std::to_string(format) +
64         ".pcm";
65     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
66     playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, sessionId_);
67     recorderDfx_ = std::make_unique<RecorderDfxWriter>(processConfig_.appInfo, sessionId_);
68 }
69 
~AudioProcessInServer()70 AudioProcessInServer::~AudioProcessInServer()
71 {
72     AUDIO_INFO_LOG("~AudioProcessInServer()");
73     if (object_ != nullptr) {
74         bool res = object_->RemoveDeathRecipient(deathRecipient_);
75         AUDIO_INFO_LOG("RemoveDeathRecipient ret: %{public}d", res);
76     }
77 
78     if (convertedBuffer_.buffer != nullptr) {
79         delete [] convertedBuffer_.buffer;
80     }
81     DumpFileUtil::CloseDumpFile(&dumpFile_);
82     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
83         TurnOffMicIndicator(CAPTURER_INVALID);
84     }
85 }
86 
GetSessionId(uint32_t & sessionId)87 int32_t AudioProcessInServer::GetSessionId(uint32_t &sessionId)
88 {
89     sessionId = sessionId_;
90     return SUCCESS;
91 }
92 
SetNonInterruptMute(const bool muteFlag)93 void AudioProcessInServer::SetNonInterruptMute(const bool muteFlag)
94 {
95     muteFlag_ = muteFlag;
96     AUDIO_INFO_LOG("muteFlag_: %{public}d", muteFlag);
97     AudioService::GetInstance()->UpdateMuteControlSet(sessionId_, muteFlag);
98 }
99 
GetMuteState()100 bool AudioProcessInServer::GetMuteState()
101 {
102     return muteFlag_ || silentModeAndMixWithOthers_;
103 }
104 
GetSessionId()105 uint32_t AudioProcessInServer::GetSessionId()
106 {
107     return sessionId_;
108 }
109 
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)110 int32_t AudioProcessInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
111 {
112     if (processBuffer_ == nullptr || processBuffer_->GetStreamStatus() == nullptr) {
113         AUDIO_ERR_LOG("GetStandbyStatus failed, buffer is nullptr.");
114         return ERR_OPERATION_FAILED;
115     }
116     isStandby = processBuffer_->GetStreamStatus()->load() == STREAM_STAND_BY;
117     if (isStandby) {
118         enterStandbyTime = enterStandbyTime_;
119     } else {
120         enterStandbyTime = 0;
121     }
122 
123     return SUCCESS;
124 }
125 
EnableStandby()126 void AudioProcessInServer::EnableStandby()
127 {
128     CHECK_AND_RETURN_LOG(processBuffer_ != nullptr && processBuffer_->GetStreamStatus() != nullptr, "failed: nullptr");
129     processBuffer_->GetStreamStatus()->store(StreamStatus::STREAM_STAND_BY);
130     enterStandbyTime_ = ClockTime::GetCurNano();
131 
132     WriterRenderStreamStandbySysEvent(sessionId_, 1);
133 }
134 
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)135 int32_t AudioProcessInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
136 {
137     AUDIO_INFO_LOG("ResolveBuffer start");
138     CHECK_AND_RETURN_RET_LOG(isBufferConfiged_, ERR_ILLEGAL_STATE,
139         "ResolveBuffer failed, buffer is not configed.");
140 
141     if (processBuffer_ == nullptr) {
142         AUDIO_ERR_LOG("ResolveBuffer failed, buffer is nullptr.");
143     }
144     buffer = processBuffer_;
145     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, ERR_ILLEGAL_STATE, "ResolveBuffer failed, processBuffer_ is null.");
146 
147     return SUCCESS;
148 }
149 
RequestHandleInfo(bool isAsync)150 int32_t AudioProcessInServer::RequestHandleInfo(bool isAsync)
151 {
152     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
153     CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_ILLEGAL_STATE, "buffer not inited!");
154 
155     for (size_t i = 0; i < listenerList_.size(); i++) {
156         listenerList_[i]->OnUpdateHandleInfo(this);
157     }
158     return SUCCESS;
159 }
160 
TurnOnMicIndicator(CapturerState capturerState)161 bool AudioProcessInServer::TurnOnMicIndicator(CapturerState capturerState)
162 {
163     uint32_t tokenId = processConfig_.appInfo.appTokenId;
164     uint64_t fullTokenId = processConfig_.appInfo.appFullTokenId;
165     SwitchStreamInfo info = {
166         sessionId_,
167         processConfig_.callerUid,
168         processConfig_.appInfo.appUid,
169         processConfig_.appInfo.appPid,
170         tokenId,
171         capturerState,
172     };
173     if (!SwitchStreamUtil::IsSwitchStreamSwitching(info, SWITCH_STATE_STARTED)) {
174         CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId),
175             false, "VerifyBackgroundCapture failed!");
176     }
177     SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_STARTED);
178 
179     if (isMicIndicatorOn_) {
180         AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already on."
181             "No need to call NotifyPrivacyStart!", sessionId_);
182     } else {
183         CHECK_AND_RETURN_RET_LOG(PermissionUtil::NotifyPrivacyStart(tokenId, sessionId_),
184             false, "NotifyPrivacyStart failed!");
185         AUDIO_INFO_LOG("Turn on micIndicator of stream:%{public}d from off"
186             "after NotifyPrivacyStart success!", sessionId_);
187         isMicIndicatorOn_ = true;
188     }
189     return true;
190 }
191 
TurnOffMicIndicator(CapturerState capturerState)192 bool AudioProcessInServer::TurnOffMicIndicator(CapturerState capturerState)
193 {
194     uint32_t tokenId = processConfig_.appInfo.appTokenId;
195     SwitchStreamInfo info = {
196         sessionId_,
197         processConfig_.callerUid,
198         processConfig_.appInfo.appUid,
199         processConfig_.appInfo.appPid,
200         tokenId,
201         capturerState,
202     };
203     SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_FINISHED);
204 
205     if (isMicIndicatorOn_) {
206         PermissionUtil::NotifyPrivacyStop(tokenId, sessionId_);
207         AUDIO_INFO_LOG("Turn off micIndicator of stream:%{public}d from on after NotifyPrivacyStop!", sessionId_);
208         isMicIndicatorOn_ = false;
209     } else {
210         AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already off."
211             "No need to call NotifyPrivacyStop!", sessionId_);
212     }
213     return true;
214 }
215 
Start()216 int32_t AudioProcessInServer::Start()
217 {
218     int32_t ret = StartInner();
219     if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
220         RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
221         playerDfx_->WriteDfxStartMsg(sessionId_, stage, sourceDuration_, processConfig_);
222     } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
223         CapturerStage stage = ret == SUCCESS ? CAPTURER_STAGE_START_OK : CAPTURER_STAGE_START_FAIL;
224         recorderDfx_->WriteDfxStartMsg(sessionId_, stage, processConfig_);
225     }
226 
227     lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
228         std::chrono::system_clock::now().time_since_epoch()).count();
229     if (processBuffer_ != nullptr) {
230         lastWriteFrame_ = processBuffer_->GetCurReadFrame();
231     }
232     lastWriteMuteFrame_ = 0;
233     return ret;
234 }
235 
StartInner()236 int32_t AudioProcessInServer::StartInner()
237 {
238     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
239 
240     std::lock_guard<std::mutex> lock(statusLock_);
241     CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STARTING || streamStatus_->load() == STREAM_STAND_BY,
242         ERR_ILLEGAL_STATE, "Start failed, invalid status.");
243 
244     if (processConfig_.audioMode == AUDIO_MODE_RECORD && !needCheckBackground_ &&
245         PermissionUtil::NeedVerifyBackgroundCapture(processConfig_.callerUid, processConfig_.capturerInfo.sourceType)) {
246         AUDIO_INFO_LOG("set needCheckBackground_: true");
247         needCheckBackground_ = true;
248     }
249 
250     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
251         CHECK_AND_RETURN_RET_LOG(TurnOnMicIndicator(CAPTURER_RUNNING), ERR_PERMISSION_DENIED,
252             "Turn on micIndicator failed or check backgroud capture failed for stream:%{public}d!", sessionId_);
253     }
254 
255     for (size_t i = 0; i < listenerList_.size(); i++) {
256         listenerList_[i]->OnStart(this);
257     }
258     if (streamStatus_->load() == STREAM_STAND_BY) {
259         AUDIO_INFO_LOG("Call start while in stand-by, session %{public}u", sessionId_);
260         WriterRenderStreamStandbySysEvent(sessionId_, 0);
261         streamStatus_->store(STREAM_STARTING);
262         enterStandbyTime_ = 0;
263     }
264 
265     processBuffer_->SetLastWrittenTime(ClockTime::GetCurNano());
266     AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(sessionId_);
267     AUDIO_INFO_LOG("Start in server success!");
268     return SUCCESS;
269 }
270 
Pause(bool isFlush)271 int32_t AudioProcessInServer::Pause(bool isFlush)
272 {
273     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
274 
275     (void)isFlush;
276     std::lock_guard<std::mutex> lock(statusLock_);
277     CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_PAUSING,
278         ERR_ILLEGAL_STATE, "Pause failed, invalid status.");
279 
280     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
281         TurnOffMicIndicator(CAPTURER_PAUSED);
282     }
283 
284     for (size_t i = 0; i < listenerList_.size(); i++) {
285         listenerList_[i]->OnPause(this);
286     }
287 
288     if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
289         playerDfx_->WriteDfxActionMsg(sessionId_, RENDERER_STAGE_PAUSE_OK);
290     } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
291         recorderDfx_->WriteDfxActionMsg(sessionId_, CAPTURER_STAGE_PAUSE_OK);
292     }
293 
294     AUDIO_PRERELEASE_LOGI("Pause in server success!");
295     return SUCCESS;
296 }
297 
Resume()298 int32_t AudioProcessInServer::Resume()
299 {
300     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
301     std::lock_guard<std::mutex> lock(statusLock_);
302     CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STARTING,
303         ERR_ILLEGAL_STATE, "Resume failed, invalid status.");
304     if (processConfig_.audioMode == AUDIO_MODE_RECORD && !needCheckBackground_ &&
305         PermissionUtil::NeedVerifyBackgroundCapture(processConfig_.callerUid, processConfig_.capturerInfo.sourceType)) {
306         AUDIO_INFO_LOG("set needCheckBackground_: true");
307         needCheckBackground_ = true;
308     }
309 
310     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
311         CHECK_AND_RETURN_RET_LOG(TurnOnMicIndicator(CAPTURER_RUNNING), ERR_PERMISSION_DENIED,
312             "Turn on micIndicator failed or check backgroud capture failed for stream:%{public}d!", sessionId_);
313     }
314 
315     for (size_t i = 0; i < listenerList_.size(); i++) {
316         listenerList_[i]->OnStart(this);
317     }
318     AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(sessionId_);
319     AUDIO_PRERELEASE_LOGI("Resume in server success!");
320     return SUCCESS;
321 }
322 
Stop()323 int32_t AudioProcessInServer::Stop()
324 {
325     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
326 
327     std::lock_guard<std::mutex> lock(statusLock_);
328     CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STOPPING,
329         ERR_ILLEGAL_STATE, "Stop failed, invalid status.");
330 
331     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
332         TurnOffMicIndicator(CAPTURER_STOPPED);
333     }
334 
335     for (size_t i = 0; i < listenerList_.size(); i++) {
336         listenerList_[i]->OnPause(this); // notify endpoint?
337     }
338 
339     lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
340         std::chrono::system_clock::now().time_since_epoch()).count();
341     if (processBuffer_ != nullptr) {
342         lastWriteFrame_ = processBuffer_->GetCurReadFrame() - lastWriteFrame_;
343     }
344     if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
345         playerDfx_->WriteDfxStopMsg(sessionId_, RENDERER_STAGE_STOP_OK,
346             {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
347     } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
348         recorderDfx_->WriteDfxStopMsg(sessionId_, CAPTURER_STAGE_STOP_OK,
349             GetLastAudioDuration(), processConfig_);
350     }
351 
352     AUDIO_INFO_LOG("Stop in server success!");
353     return SUCCESS;
354 }
355 
Release(bool isSwitchStream)356 int32_t AudioProcessInServer::Release(bool isSwitchStream)
357 {
358     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited or already released");
359     UnscheduleReportData(processConfig_.appInfo.appPid, clientTid_, clientBundleName_.c_str());
360     clientThreadPriorityRequested_ = false;
361     isInited_ = false;
362     std::lock_guard<std::mutex> lock(statusLock_);
363     CHECK_AND_RETURN_RET_LOG(releaseCallback_ != nullptr, ERR_OPERATION_FAILED, "Failed: no service to notify.");
364 
365     if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
366         TurnOffMicIndicator(CAPTURER_RELEASED);
367     }
368 
369     int32_t ret = releaseCallback_->OnProcessRelease(this, isSwitchStream);
370     AUDIO_INFO_LOG("notify service release result: %{public}d", ret);
371     return SUCCESS;
372 }
373 
ProcessDeathRecipient(AudioProcessInServer * processInServer,ProcessReleaseCallback * processHolder)374 ProcessDeathRecipient::ProcessDeathRecipient(AudioProcessInServer *processInServer,
375     ProcessReleaseCallback *processHolder)
376 {
377     processInServer_ = processInServer;
378     processHolder_ = processHolder;
379     createTime_ = ClockTime::GetCurNano();
380     AUDIO_INFO_LOG("OnRemoteDied create time: %{public}" PRId64 "", createTime_);
381 }
382 
OnRemoteDied(const wptr<IRemoteObject> & remote)383 void ProcessDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
384 {
385     CHECK_AND_RETURN_LOG(processHolder_ != nullptr, "processHolder_ is null.");
386     int32_t ret = processHolder_->OnProcessRelease(processInServer_);
387     AUDIO_INFO_LOG("OnRemoteDied ret: %{public}d %{public}" PRId64 "", ret, createTime_);
388 }
389 
RegisterProcessCb(sptr<IRemoteObject> object)390 int32_t AudioProcessInServer::RegisterProcessCb(sptr<IRemoteObject> object)
391 {
392     sptr<IProcessCb> processCb = iface_cast<IProcessCb>(object);
393     CHECK_AND_RETURN_RET_LOG(processCb != nullptr, ERR_INVALID_PARAM, "RegisterProcessCb obj cast failed");
394     deathRecipient_ = new ProcessDeathRecipient(this, releaseCallback_);
395     bool result = object->AddDeathRecipient(deathRecipient_);
396     CHECK_AND_RETURN_RET_LOG(result, ERR_OPERATION_FAILED, "AddDeathRecipient failed.");
397     object_= object;
398     return SUCCESS;
399 }
400 
SetInnerCapState(bool isInnerCapped,int32_t innerCapId)401 void AudioProcessInServer::SetInnerCapState(bool isInnerCapped, int32_t innerCapId)
402 {
403     AUDIO_INFO_LOG("process[%{public}u] innercapped: %{public}s, innerCapId:%{public}d",
404         sessionId_, isInnerCapped ? "true" : "false", innerCapId);
405     innerCapStates_[innerCapId] = isInnerCapped;
406 }
407 
GetInnerCapState(int32_t innerCapId)408 bool AudioProcessInServer::GetInnerCapState(int32_t innerCapId)
409 {
410     if (innerCapStates_.count(innerCapId) && innerCapStates_[innerCapId]) {
411         return true;
412     }
413     return false;
414 }
415 
GetInnerCapState()416 std::unordered_map<int32_t, bool> AudioProcessInServer::GetInnerCapState()
417 {
418     return  innerCapStates_;
419 }
420 
GetAppInfo()421 AppInfo AudioProcessInServer::GetAppInfo()
422 {
423     return processConfig_.appInfo;
424 }
425 
GetConvertedBuffer()426 BufferDesc &AudioProcessInServer::GetConvertedBuffer()
427 {
428     return convertedBuffer_;
429 }
430 
Dump(int fd,const std::vector<std::u16string> & args)431 int AudioProcessInServer::Dump(int fd, const std::vector<std::u16string> &args)
432 {
433     return SUCCESS;
434 }
435 
Dump(std::string & dumpString)436 void AudioProcessInServer::Dump(std::string &dumpString)
437 {
438     AppendFormat(dumpString, "\n  - uid: %d\n", processConfig_.appInfo.appUid);
439     AppendFormat(dumpString, "- pid: %d\n", processConfig_.appInfo.appUid);
440     dumpString += "process info:\n";
441     dumpString += "stream info:\n";
442     AppendFormat(dumpString, "  - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
443     AppendFormat(dumpString, "  - channels: %d\n", processConfig_.streamInfo.channels);
444     AppendFormat(dumpString, "  - format: %d\n", processConfig_.streamInfo.format);
445     AppendFormat(dumpString, "  - encoding: %d\n", processConfig_.streamInfo.encoding);
446     if (streamStatus_ != nullptr) {
447         AppendFormat(dumpString, "  - Status: %d\n", streamStatus_->load());
448     }
449     dumpString += "\n";
450 }
451 
GetStreamBuffer()452 std::shared_ptr<OHAudioBuffer> AudioProcessInServer::GetStreamBuffer()
453 {
454     CHECK_AND_RETURN_RET_LOG(isBufferConfiged_ && processBuffer_ != nullptr,
455         nullptr, "GetStreamBuffer failed:process buffer not config.");
456     return processBuffer_;
457 }
458 
GetStreamInfo()459 AudioStreamInfo AudioProcessInServer::GetStreamInfo()
460 {
461     return processConfig_.streamInfo;
462 }
463 
GetAudioSessionId()464 uint32_t AudioProcessInServer::GetAudioSessionId()
465 {
466     return sessionId_;
467 }
468 
GetAudioStreamType()469 AudioStreamType AudioProcessInServer::GetAudioStreamType()
470 {
471     return processConfig_.streamType;
472 }
473 
GetAudioProcessConfig()474 AudioProcessConfig AudioProcessInServer::GetAudioProcessConfig()
475 {
476     return processConfig_;
477 }
478 
PcmFormatToBits(AudioSampleFormat format)479 inline uint32_t PcmFormatToBits(AudioSampleFormat format)
480 {
481     switch (format) {
482         case SAMPLE_U8:
483             return 1; // 1 byte
484         case SAMPLE_S16LE:
485             return 2; // 2 byte
486         case SAMPLE_S24LE:
487             return 3; // 3 byte
488         case SAMPLE_S32LE:
489             return 4; // 4 byte
490         case SAMPLE_F32LE:
491             return 4; // 4 byte
492         default:
493             return 2; // 2 byte
494     }
495 }
496 
InitBufferStatus()497 int32_t AudioProcessInServer::InitBufferStatus()
498 {
499     CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_ILLEGAL_STATE,
500         "InitBufferStatus failed, null buffer.");
501 
502     uint32_t spanCount = processBuffer_->GetSpanCount();
503     for (uint32_t i = 0; i < spanCount; i++) {
504         SpanInfo *spanInfo = processBuffer_->GetSpanInfoByIndex(i);
505         CHECK_AND_RETURN_RET_LOG(spanInfo != nullptr, ERR_ILLEGAL_STATE,
506             "InitBufferStatus failed, null spaninfo");
507         spanInfo->spanStatus = SPAN_READ_DONE;
508         spanInfo->offsetInFrame = 0;
509 
510         spanInfo->readStartTime = 0;
511         spanInfo->readDoneTime = 0;
512 
513         spanInfo->writeStartTime = 0;
514         spanInfo->writeDoneTime = 0;
515 
516         spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
517         spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
518         spanInfo->isMute = false;
519     }
520     processBuffer_->SetLastWrittenTime(ClockTime::GetCurNano());
521     return SUCCESS;
522 }
523 
ConfigProcessBuffer(uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,DeviceStreamInfo & serverStreamInfo,const std::shared_ptr<OHAudioBuffer> & buffer)524 int32_t AudioProcessInServer::ConfigProcessBuffer(uint32_t &totalSizeInframe,
525     uint32_t &spanSizeInframe, DeviceStreamInfo &serverStreamInfo, const std::shared_ptr<OHAudioBuffer> &buffer)
526 {
527     if (processBuffer_ != nullptr) {
528         AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
529         return SUCCESS;
530     }
531     // check
532     CHECK_AND_RETURN_RET_LOG(totalSizeInframe != 0 && spanSizeInframe != 0 && totalSizeInframe % spanSizeInframe == 0,
533         ERR_INVALID_PARAM, "ConfigProcessBuffer failed: ERR_INVALID_PARAM");
534     CHECK_AND_RETURN_RET_LOG(serverStreamInfo.samplingRate.size() > 0 && serverStreamInfo.channels.size() > 0,
535         ERR_INVALID_PARAM, "Invalid stream info in server");
536     uint32_t spanTime = spanSizeInframe * AUDIO_MS_PER_SECOND / *serverStreamInfo.samplingRate.rbegin();
537     spanSizeInframe_ = spanTime * processConfig_.streamInfo.samplingRate / AUDIO_MS_PER_SECOND;
538     totalSizeInframe_ = totalSizeInframe / spanSizeInframe * spanSizeInframe_;
539 
540     uint32_t channel = processConfig_.streamInfo.channels;
541     uint32_t formatbyte = PcmFormatToBits(processConfig_.streamInfo.format);
542     byteSizePerFrame_ = channel * formatbyte;
543     if (*serverStreamInfo.channels.rbegin() != processConfig_.streamInfo.channels ||
544         serverStreamInfo.format != processConfig_.streamInfo.format) {
545         size_t spanSizeInByte = 0;
546         if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
547             uint32_t serverByteSize = *serverStreamInfo.channels.rbegin() * PcmFormatToBits(serverStreamInfo.format);
548             spanSizeInByte = static_cast<size_t>(spanSizeInframe * serverByteSize);
549         } else {
550             spanSizeInByte = static_cast<size_t>(spanSizeInframe_ * byteSizePerFrame_);
551         }
552         convertedBuffer_.buffer = new uint8_t[spanSizeInByte];
553         convertedBuffer_.bufLength = spanSizeInByte;
554         convertedBuffer_.dataLength = spanSizeInByte;
555     }
556 
557     if (buffer == nullptr) {
558         // create OHAudioBuffer in server.
559         processBuffer_ = OHAudioBuffer::CreateFromLocal(totalSizeInframe_, spanSizeInframe_, byteSizePerFrame_);
560         CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
561 
562         CHECK_AND_RETURN_RET_LOG(processBuffer_->GetBufferHolder() == AudioBufferHolder::AUDIO_SERVER_SHARED,
563             ERR_ILLEGAL_STATE, "CreateFormLocal in server failed.");
564         AUDIO_INFO_LOG("Config: totalSizeInframe:%{public}d spanSizeInframe:%{public}d byteSizePerFrame:%{public}d",
565             totalSizeInframe_, spanSizeInframe_, byteSizePerFrame_);
566 
567         // we need to clear data buffer to avoid dirty data.
568         memset_s(processBuffer_->GetDataBase(), processBuffer_->GetDataSize(), 0, processBuffer_->GetDataSize());
569         int32_t ret = InitBufferStatus();
570         AUDIO_DEBUG_LOG("clear data buffer, ret:%{public}d", ret);
571     } else {
572         processBuffer_ = buffer;
573         AUDIO_INFO_LOG("ConfigBuffer in server separate, base: %{public}d", *processBuffer_->GetDataBase());
574     }
575 
576     streamStatus_ = processBuffer_->GetStreamStatus();
577     CHECK_AND_RETURN_RET_LOG(streamStatus_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
578     isBufferConfiged_ = true;
579     isInited_ = true;
580     return SUCCESS;
581 }
582 
AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)583 int32_t AudioProcessInServer::AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
584 {
585     std::lock_guard<std::mutex> lock(listenerListLock_);
586     listenerList_.push_back(listener);
587     return SUCCESS;
588 }
589 
RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)590 int32_t AudioProcessInServer::RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
591 {
592     std::lock_guard<std::mutex> lock(listenerListLock_);
593     std::vector<std::shared_ptr<IProcessStatusListener>>::iterator it = listenerList_.begin();
594     bool isFind = false;
595     while (it != listenerList_.end()) {
596         if (*it == listener) {
597             listenerList_.erase(it);
598             isFind = true;
599             break;
600         } else {
601             it++;
602         }
603     }
604 
605     AUDIO_INFO_LOG("%{public}s the endpoint.", (isFind ? "find and remove" : "not find"));
606     return SUCCESS;
607 }
608 
RegisterThreadPriority(uint32_t tid,const std::string & bundleName)609 int32_t AudioProcessInServer::RegisterThreadPriority(uint32_t tid, const std::string &bundleName)
610 {
611     if (!clientThreadPriorityRequested_) {
612         clientTid_ = tid;
613         clientBundleName_ = bundleName;
614         ScheduleReportData(processConfig_.appInfo.appPid, tid, bundleName.c_str());
615         return SUCCESS;
616     } else {
617         AUDIO_ERR_LOG("client thread priority requested");
618         return ERR_OPERATION_FAILED;
619     }
620 }
621 
WriterRenderStreamStandbySysEvent(uint32_t sessionId,int32_t standby)622 void AudioProcessInServer::WriterRenderStreamStandbySysEvent(uint32_t sessionId, int32_t standby)
623 {
624     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
625         Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
626         Media::MediaMonitor::BEHAVIOR_EVENT);
627     bean->Add("STREAMID", static_cast<int32_t>(sessionId));
628     bean->Add("STANDBY", standby);
629     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
630 
631     std::unordered_map<std::string, std::string> payload;
632     payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
633     payload["sessionId"] = std::to_string(sessionId);
634     payload["isStandby"] = std::to_string(standby);
635     ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
636 
637     if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
638         playerDfx_->WriteDfxActionMsg(sessionId_, standby == 0 ?
639             RENDERER_STAGE_STANDBY_END : RENDERER_STAGE_STANDBY_BEGIN);
640     }
641 }
642 
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)643 void AudioProcessInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
644 {
645 #ifdef RESSCHE_ENABLE
646     AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
647     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
648 #endif
649 }
650 
WriteDumpFile(void * buffer,size_t bufferSize)651 void AudioProcessInServer::WriteDumpFile(void *buffer, size_t bufferSize)
652 {
653     if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
654         DumpFileUtil::WriteDumpFile(dumpFile_, buffer, bufferSize);
655         AudioCacheMgr::GetInstance().CacheData(dumpFileName_, buffer, bufferSize);
656     }
657 }
658 
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)659 int32_t AudioProcessInServer::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
660 {
661     return PolicyHandler::GetInstance().SetDefaultOutputDevice(defaultOutputDevice, sessionId_,
662         processConfig_.rendererInfo.streamUsage, streamStatus_->load() == STREAM_RUNNING);
663 }
664 
SetSilentModeAndMixWithOthers(bool on)665 int32_t AudioProcessInServer::SetSilentModeAndMixWithOthers(bool on)
666 {
667     silentModeAndMixWithOthers_ = on;
668     AUDIO_INFO_LOG("%{public}d", on);
669     return SUCCESS;
670 }
671 
GetStartMuteTime()672 std::time_t AudioProcessInServer::GetStartMuteTime()
673 {
674     return startMuteTime_;
675 }
676 
SetStartMuteTime(std::time_t time)677 void AudioProcessInServer::SetStartMuteTime(std::time_t time)
678 {
679     startMuteTime_ = time;
680 }
681 
GetSilentState()682 bool AudioProcessInServer::GetSilentState()
683 {
684     return isInSilentState_;
685 }
686 
SetSilentState(bool state)687 void AudioProcessInServer::SetSilentState(bool state)
688 {
689     isInSilentState_ = state;
690 }
SetSourceDuration(int64_t duration)691 int32_t AudioProcessInServer::SetSourceDuration(int64_t duration)
692 {
693     sourceDuration_ = duration;
694     return SUCCESS;
695 }
696 
SetUnderrunCount(uint32_t underrunCnt)697 int32_t AudioProcessInServer::SetUnderrunCount(uint32_t underrunCnt)
698 {
699     underrunCount_ = underrunCnt;
700     return SUCCESS;
701 }
702 
AddMuteWriteFrameCnt(int64_t muteFrameCnt)703 void AudioProcessInServer::AddMuteWriteFrameCnt(int64_t muteFrameCnt)
704 {
705     lastWriteMuteFrame_ += muteFrameCnt;
706 }
707 
GetLastAudioDuration()708 int64_t AudioProcessInServer::GetLastAudioDuration()
709 {
710     auto ret = lastStopTime_ - lastStartTime_;
711     return ret < 0 ? -1 : ret;
712 }
713 
RestoreSession(RestoreInfo restoreInfo)714 RestoreStatus AudioProcessInServer::RestoreSession(RestoreInfo restoreInfo)
715 {
716     RestoreStatus restoreStatus = processBuffer_->SetRestoreStatus(NEED_RESTORE);
717     if (restoreStatus == NEED_RESTORE) {
718         processBuffer_->SetRestoreInfo(restoreInfo);
719     }
720     return restoreStatus;
721 }
722 
723 } // namespace AudioStandard
724 } // namespace OHOS
725