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