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 #include "iprocess_cb.h"
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 #include "core_service_handler.h"
33 #include "stream_dfx_manager.h"
34 #ifdef RESSCHE_ENABLE
35 #include "res_type.h"
36 #include "res_sched_client.h"
37 #endif
38
39 namespace OHOS {
40 namespace AudioStandard {
41 namespace {
42 }
43
Create(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)44 sptr<AudioProcessInServer> AudioProcessInServer::Create(const AudioProcessConfig &processConfig,
45 ProcessReleaseCallback *releaseCallback)
46 {
47 sptr<AudioProcessInServer> process = new(std::nothrow) AudioProcessInServer(processConfig, releaseCallback);
48
49 return process;
50 }
51
AudioProcessInServer(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)52 AudioProcessInServer::AudioProcessInServer(const AudioProcessConfig &processConfig,
53 ProcessReleaseCallback *releaseCallback) : processConfig_(processConfig), releaseCallback_(releaseCallback)
54 {
55 if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) {
56 sessionId_ = PolicyHandler::GetInstance().GenerateSessionId(processConfig_.appInfo.appUid);
57 } else {
58 sessionId_ = processConfig.originalSessionId;
59 }
60
61 AudioSamplingRate samplingRate = processConfig_.streamInfo.samplingRate;
62 AudioSampleFormat format = processConfig_.streamInfo.format;
63 AudioChannel channels = processConfig_.streamInfo.channels;
64 // eg: 100005_dump_process_server_audio_48000_2_1.pcm
65 dumpFileName_ = std::to_string(sessionId_) + '_' + "_dump_process_server_audio_" +
66 std::to_string(samplingRate) + '_' + std::to_string(channels) + '_' + std::to_string(format) +
67 ".pcm";
68 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
69 playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, sessionId_);
70 recorderDfx_ = std::make_unique<RecorderDfxWriter>(processConfig_.appInfo, sessionId_);
71 if (processConfig_.audioMode == AUDIO_MODE_RECORD) {
72 AudioService::GetInstance()->RegisterMuteStateChangeCallback(sessionId_, [this](bool flag) {
73 AUDIO_INFO_LOG("recv mute state change flag %{public}d", flag ? 1 : 0);
74 muteFlag_ = flag;
75 });
76 }
77 audioStreamChecker_ = std::make_shared<AudioStreamChecker>(processConfig);
78 AudioStreamMonitor::GetInstance().AddCheckForMonitor(processConfig.originalSessionId, audioStreamChecker_);
79 }
80
~AudioProcessInServer()81 AudioProcessInServer::~AudioProcessInServer()
82 {
83 AUDIO_INFO_LOG("~AudioProcessInServer()");
84 if (object_ != nullptr) {
85 bool res = object_->RemoveDeathRecipient(deathRecipient_);
86 AUDIO_INFO_LOG("RemoveDeathRecipient ret: %{public}d", res);
87 }
88
89 if (convertedBuffer_.buffer != nullptr) {
90 delete [] convertedBuffer_.buffer;
91 }
92 DumpFileUtil::CloseDumpFile(&dumpFile_);
93 if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
94 TurnOffMicIndicator(CAPTURER_INVALID);
95 }
96 AudioStreamMonitor::GetInstance().DeleteCheckForMonitor(processConfig_.originalSessionId);
97 }
98
HandleStreamStatusToCapturerState(const StreamStatus & status)99 static CapturerState HandleStreamStatusToCapturerState(const StreamStatus &status)
100 {
101 switch (status) {
102 case STREAM_IDEL:
103 case STREAM_STAND_BY:
104 return CAPTURER_PREPARED;
105 case STREAM_STARTING:
106 case STREAM_RUNNING:
107 return CAPTURER_RUNNING;
108 case STREAM_PAUSING:
109 case STREAM_PAUSED:
110 return CAPTURER_PAUSED;
111 case STREAM_STOPPING:
112 case STREAM_STOPPED:
113 return CAPTURER_STOPPED;
114 case STREAM_RELEASED:
115 return CAPTURER_RELEASED;
116 default:
117 return CAPTURER_INVALID;
118 }
119 }
120
GetSessionId(uint32_t & sessionId)121 int32_t AudioProcessInServer::GetSessionId(uint32_t &sessionId)
122 {
123 sessionId = sessionId_;
124 return SUCCESS;
125 }
126
SetNonInterruptMute(const bool muteFlag)127 void AudioProcessInServer::SetNonInterruptMute(const bool muteFlag)
128 {
129 muteFlag_ = muteFlag;
130 AUDIO_INFO_LOG("muteFlag_: %{public}d", muteFlag);
131 AudioService::GetInstance()->UpdateMuteControlSet(sessionId_, muteFlag);
132 }
133
GetMuteState()134 bool AudioProcessInServer::GetMuteState()
135 {
136 return muteFlag_ || silentModeAndMixWithOthers_;
137 }
138
GetSessionId()139 uint32_t AudioProcessInServer::GetSessionId()
140 {
141 return sessionId_;
142 }
143
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)144 int32_t AudioProcessInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
145 {
146 if (processBuffer_ == nullptr || processBuffer_->GetStreamStatus() == nullptr) {
147 AUDIO_ERR_LOG("GetStandbyStatus failed, buffer is nullptr!");
148 return ERR_OPERATION_FAILED;
149 }
150 isStandby = processBuffer_->GetStreamStatus()->load() == STREAM_STAND_BY;
151 if (isStandby) {
152 enterStandbyTime = enterStandbyTime_;
153 } else {
154 enterStandbyTime = 0;
155 }
156
157 return SUCCESS;
158 }
159
EnableStandby()160 void AudioProcessInServer::EnableStandby()
161 {
162 CHECK_AND_RETURN_LOG(processBuffer_ != nullptr && processBuffer_->GetStreamStatus() != nullptr, "failed: nullptr!");
163 processBuffer_->GetStreamStatus()->store(StreamStatus::STREAM_STAND_BY);
164 enterStandbyTime_ = ClockTime::GetCurNano();
165 audioStreamChecker_->RecordStandbyTime(true);
166 WriterRenderStreamStandbySysEvent(sessionId_, 1);
167 }
168
ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> & buffer,uint32_t & spanSizeInFrame)169 int32_t AudioProcessInServer::ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> &buffer,
170 uint32_t &spanSizeInFrame)
171 {
172 AUDIO_INFO_LOG("ResolveBuffer start");
173 CHECK_AND_RETURN_RET_LOG(isBufferConfiged_, ERR_ILLEGAL_STATE,
174 "ResolveBuffer failed, buffer is not configed!");
175
176 if (processBuffer_ == nullptr) {
177 AUDIO_ERR_LOG("ResolveBuffer failed, buffer is nullptr!");
178 }
179 buffer = processBuffer_;
180 spanSizeInFrame = spanSizeInframe_;
181 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, ERR_ILLEGAL_STATE, "ResolveBuffer failed, processBuffer_ is nullptr!");
182
183 return SUCCESS;
184 }
185
RequestHandleInfo()186 int32_t AudioProcessInServer::RequestHandleInfo()
187 {
188 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
189 CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_ILLEGAL_STATE, "buffer not inited!");
190
191 for (size_t i = 0; i < listenerList_.size(); i++) {
192 listenerList_[i]->OnUpdateHandleInfo(this);
193 }
194 return SUCCESS;
195 }
196
RequestHandleInfoAsync()197 int32_t AudioProcessInServer::RequestHandleInfoAsync()
198 {
199 return RequestHandleInfo();
200 }
201
202
CheckBGCapturer()203 bool AudioProcessInServer::CheckBGCapturer()
204 {
205 uint32_t tokenId = processConfig_.appInfo.appTokenId;
206 uint64_t fullTokenId = processConfig_.appInfo.appFullTokenId;
207
208 if (PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId)) {
209 return true;
210 }
211
212 CHECK_AND_RETURN_RET_LOG(processConfig_.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION &&
213 AudioService::GetInstance()->InForegroundList(processConfig_.appInfo.appUid), false, "Verify failed");
214
215 AudioService::GetInstance()->UpdateForegroundState(tokenId, true);
216 bool res = PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId);
217 AUDIO_INFO_LOG("Retry result:%{public}s", (res ? "success" : "fail"));
218 AudioService::GetInstance()->UpdateForegroundState(tokenId, false);
219
220 return res;
221 }
222
TurnOnMicIndicator(CapturerState capturerState)223 bool AudioProcessInServer::TurnOnMicIndicator(CapturerState capturerState)
224 {
225 uint32_t tokenId = processConfig_.appInfo.appTokenId;
226 SwitchStreamInfo info = {
227 sessionId_,
228 processConfig_.callerUid,
229 processConfig_.appInfo.appUid,
230 processConfig_.appInfo.appPid,
231 tokenId,
232 capturerState,
233 };
234 if (!SwitchStreamUtil::IsSwitchStreamSwitching(info, SWITCH_STATE_STARTED)) {
235 CHECK_AND_RETURN_RET_LOG(CheckBGCapturer(), false, "Verify failed");
236 }
237 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_STARTED);
238
239 if (isMicIndicatorOn_) {
240 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already on."
241 "No need to call NotifyPrivacyStart!", sessionId_);
242 } else {
243 CHECK_AND_RETURN_RET_LOG(PermissionUtil::NotifyPrivacyStart(tokenId, sessionId_),
244 false, "NotifyPrivacyStart failed!");
245 AUDIO_INFO_LOG("Turn on micIndicator of stream:%{public}d from off "
246 "after NotifyPrivacyStart success!", sessionId_);
247 isMicIndicatorOn_ = true;
248 }
249 return true;
250 }
251
TurnOffMicIndicator(CapturerState capturerState)252 bool AudioProcessInServer::TurnOffMicIndicator(CapturerState capturerState)
253 {
254 uint32_t tokenId = processConfig_.appInfo.appTokenId;
255 SwitchStreamInfo info = {
256 sessionId_,
257 processConfig_.callerUid,
258 processConfig_.appInfo.appUid,
259 processConfig_.appInfo.appPid,
260 tokenId,
261 capturerState,
262 };
263 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_FINISHED);
264
265 if (isMicIndicatorOn_) {
266 PermissionUtil::NotifyPrivacyStop(tokenId, sessionId_);
267 AUDIO_INFO_LOG("Turn off micIndicator of stream:%{public}d from on after NotifyPrivacyStop!", sessionId_);
268 isMicIndicatorOn_ = false;
269 } else {
270 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already off."
271 "No need to call NotifyPrivacyStop!", sessionId_);
272 }
273 return true;
274 }
275
Start()276 int32_t AudioProcessInServer::Start()
277 {
278 int32_t ret = StartInner();
279 if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
280 RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
281 playerDfx_->WriteDfxStartMsg(sessionId_, stage, sourceDuration_, processConfig_);
282 } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
283 CapturerStage stage = ret == SUCCESS ? CAPTURER_STAGE_START_OK : CAPTURER_STAGE_START_FAIL;
284 recorderDfx_->WriteDfxStartMsg(sessionId_, stage, processConfig_);
285 }
286
287 lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
288 std::chrono::system_clock::now().time_since_epoch()).count();
289 if (processBuffer_ != nullptr) {
290 lastWriteFrame_ = static_cast<int64_t>(processBuffer_->GetCurReadFrame());
291 }
292 lastWriteMuteFrame_ = 0;
293 return ret;
294 }
295
StartInner()296 int32_t AudioProcessInServer::StartInner()
297 {
298 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
299
300 std::lock_guard<std::mutex> lock(statusLock_);
301 CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STARTING || streamStatus_->load() == STREAM_STAND_BY,
302 ERR_ILLEGAL_STATE, "Start failed, invalid status.");
303
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 int32_t ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_START);
316 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy start client failed, reason: %{public}d", ret);
317 StreamDfxManager::GetInstance().CheckStreamOccupancy(sessionId_, processConfig_, true);
318 for (size_t i = 0; i < listenerList_.size(); i++) {
319 listenerList_[i]->OnStart(this);
320 }
321 if (streamStatus_->load() == STREAM_STAND_BY) {
322 AUDIO_INFO_LOG("Call start while in stand-by, session %{public}u", sessionId_);
323 WriterRenderStreamStandbySysEvent(sessionId_, 0);
324 streamStatus_->store(STREAM_STARTING);
325 enterStandbyTime_ = 0;
326 audioStreamChecker_->RecordStandbyTime(false);
327 } else {
328 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_START, false);
329 }
330
331 processBuffer_->SetLastWrittenTime(ClockTime::GetCurNano());
332 AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(sessionId_, processConfig_.appInfo.appTokenId);
333 AUDIO_INFO_LOG("Start in server success!");
334 return SUCCESS;
335 }
336
Pause(bool isFlush)337 int32_t AudioProcessInServer::Pause(bool isFlush)
338 {
339 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
340
341 (void)isFlush;
342
343 {
344 std::lock_guard lock(scheduleGuardsMutex_);
345 scheduleGuards_[METHOD_START] = nullptr;
346 }
347
348 std::lock_guard<std::mutex> lock(statusLock_);
349 CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_PAUSING,
350 ERR_ILLEGAL_STATE, "Pause failed, invalid status.");
351
352 if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
353 TurnOffMicIndicator(CAPTURER_PAUSED);
354 }
355
356 for (size_t i = 0; i < listenerList_.size(); i++) {
357 listenerList_[i]->OnPause(this);
358 }
359 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_PAUSE, false);
360 if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
361 playerDfx_->WriteDfxActionMsg(sessionId_, RENDERER_STAGE_PAUSE_OK);
362 } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
363 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
364 std::chrono::system_clock::now().time_since_epoch()).count();
365 recorderDfx_->WriteDfxStopMsg(sessionId_, CAPTURER_STAGE_PAUSE_OK,
366 GetLastAudioDuration(), processConfig_);
367 }
368 CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_PAUSE);
369 StreamDfxManager::GetInstance().CheckStreamOccupancy(sessionId_, processConfig_, false);
370 AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(sessionId_);
371 AUDIO_PRERELEASE_LOGI("Pause in server success!");
372 return SUCCESS;
373 }
374
Resume()375 int32_t AudioProcessInServer::Resume()
376 {
377 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
378 std::lock_guard<std::mutex> lock(statusLock_);
379 CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STARTING,
380 ERR_ILLEGAL_STATE, "Resume failed, invalid status.");
381 if (processConfig_.audioMode == AUDIO_MODE_RECORD && !needCheckBackground_ &&
382 PermissionUtil::NeedVerifyBackgroundCapture(processConfig_.callerUid, processConfig_.capturerInfo.sourceType)) {
383 AUDIO_INFO_LOG("set needCheckBackground_: true");
384 needCheckBackground_ = true;
385 }
386 if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
387 CHECK_AND_RETURN_RET_LOG(TurnOnMicIndicator(CAPTURER_RUNNING), ERR_PERMISSION_DENIED,
388 "Turn on micIndicator failed or check backgroud capture failed for stream:%{public}d!", sessionId_);
389 }
390
391 for (size_t i = 0; i < listenerList_.size(); i++) {
392 listenerList_[i]->OnStart(this);
393 }
394 AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(sessionId_, processConfig_.appInfo.appTokenId);
395 processBuffer_->SetLastWrittenTime(ClockTime::GetCurNano());
396 CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_START);
397 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_START, false);
398 AUDIO_PRERELEASE_LOGI("Resume in server success!");
399 return SUCCESS;
400 }
401
Stop(int32_t stage)402 int32_t AudioProcessInServer::Stop(int32_t stage)
403 {
404 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
405
406 {
407 std::lock_guard lock(scheduleGuardsMutex_);
408 scheduleGuards_[METHOD_START] = nullptr;
409 }
410
411 std::lock_guard<std::mutex> lock(statusLock_);
412 CHECK_AND_RETURN_RET_LOG(streamStatus_->load() == STREAM_STOPPING,
413 ERR_ILLEGAL_STATE, "Stop failed, invalid status.");
414 if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
415 TurnOffMicIndicator(CAPTURER_STOPPED);
416 }
417 for (size_t i = 0; i < listenerList_.size(); i++) {
418 listenerList_[i]->OnPause(this); // notify endpoint?
419 }
420
421 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
422 std::chrono::system_clock::now().time_since_epoch()).count();
423 if (processBuffer_ != nullptr) {
424 lastWriteFrame_ = static_cast<int64_t>(processBuffer_->GetCurReadFrame()) - lastWriteFrame_;
425 }
426 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_STOP, false);
427 if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
428 RendererStage rendererStage = stage == AUDIO_PROC_STAGE_STOP_BY_RELEASE ?
429 RENDERER_STAGE_STOP_BY_RELEASE : RENDERER_STAGE_STOP_OK;
430 playerDfx_->WriteDfxStopMsg(sessionId_, rendererStage,
431 {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
432 } else if (recorderDfx_ && processConfig_.audioMode == AUDIO_MODE_RECORD) {
433 CapturerStage capturerStage = stage == AUDIO_PROC_STAGE_STOP_BY_RELEASE ?
434 CAPTURER_STAGE_STOP_BY_RELEASE : CAPTURER_STAGE_STOP_OK;
435 recorderDfx_->WriteDfxStopMsg(sessionId_, capturerStage,
436 GetLastAudioDuration(), processConfig_);
437 }
438 CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_STOP);
439 StreamDfxManager::GetInstance().CheckStreamOccupancy(sessionId_, processConfig_, false);
440 AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(sessionId_);
441 AUDIO_INFO_LOG("Stop in server success!");
442 return SUCCESS;
443 }
444
Release(bool isSwitchStream)445 int32_t AudioProcessInServer::Release(bool isSwitchStream)
446 {
447 CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited or already released");
448 {
449 std::lock_guard lock(scheduleGuardsMutex_);
450 scheduleGuards_[METHOD_WRITE_OR_READ] = nullptr;
451 scheduleGuards_[METHOD_START] = nullptr;
452 }
453 isInited_ = false;
454 std::lock_guard<std::mutex> lock(statusLock_);
455 CHECK_AND_RETURN_RET_LOG(releaseCallback_ != nullptr, ERR_OPERATION_FAILED, "Failed: no service to notify.");
456
457 if (processConfig_.audioMode == AUDIO_MODE_RECORD && needCheckBackground_) {
458 TurnOffMicIndicator(CAPTURER_RELEASED);
459 }
460 int32_t ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_RELEASE);
461 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy remove client failed, reason: %{public}d", ret);
462 StreamDfxManager::GetInstance().CheckStreamOccupancy(sessionId_, processConfig_, false);
463 ret = releaseCallback_->OnProcessRelease(this, isSwitchStream);
464 AUDIO_INFO_LOG("notify service release result: %{public}d", ret);
465 return SUCCESS;
466 }
467
ProcessDeathRecipient(AudioProcessInServer * processInServer,ProcessReleaseCallback * processHolder)468 ProcessDeathRecipient::ProcessDeathRecipient(AudioProcessInServer *processInServer,
469 ProcessReleaseCallback *processHolder)
470 {
471 processInServer_ = processInServer;
472 processHolder_ = processHolder;
473 createTime_ = ClockTime::GetCurNano();
474 AUDIO_INFO_LOG("OnRemoteDied create time: %{public}" PRId64 "", createTime_);
475 }
476
OnRemoteDied(const wptr<IRemoteObject> & remote)477 void ProcessDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
478 {
479 CHECK_AND_RETURN_LOG(processHolder_ != nullptr, "processHolder_ is null.");
480 int32_t ret = processHolder_->OnProcessRelease(processInServer_);
481 AUDIO_INFO_LOG("OnRemoteDied ret: %{public}d %{public}" PRId64 "", ret, createTime_);
482 }
483
RegisterProcessCb(const sptr<IRemoteObject> & object)484 int32_t AudioProcessInServer::RegisterProcessCb(const sptr<IRemoteObject>& object)
485 {
486 sptr<IProcessCb> processCb = iface_cast<IProcessCb>(object);
487 CHECK_AND_RETURN_RET_LOG(processCb != nullptr, ERR_INVALID_PARAM, "RegisterProcessCb obj cast failed");
488 deathRecipient_ = new ProcessDeathRecipient(this, releaseCallback_);
489 bool result = object->AddDeathRecipient(deathRecipient_);
490 CHECK_AND_RETURN_RET_LOG(result, ERR_OPERATION_FAILED, "AddDeathRecipient failed.");
491 object_= object;
492 return SUCCESS;
493 }
494
SetInnerCapState(bool isInnerCapped,int32_t innerCapId)495 void AudioProcessInServer::SetInnerCapState(bool isInnerCapped, int32_t innerCapId)
496 {
497 AUDIO_INFO_LOG("process[%{public}u] innercapped: %{public}s, innerCapId:%{public}d",
498 sessionId_, isInnerCapped ? "true" : "false", innerCapId);
499 std::lock_guard<std::mutex> lock(innerCapStateMutex_);
500 innerCapStates_[innerCapId] = isInnerCapped;
501 }
502
GetInnerCapState(int32_t innerCapId)503 bool AudioProcessInServer::GetInnerCapState(int32_t innerCapId)
504 {
505 std::lock_guard<std::mutex> lock(innerCapStateMutex_);
506 if (innerCapStates_.count(innerCapId) && innerCapStates_[innerCapId]) {
507 return true;
508 }
509 return false;
510 }
511
GetInnerCapState()512 std::unordered_map<int32_t, bool> AudioProcessInServer::GetInnerCapState()
513 {
514 std::lock_guard<std::mutex> lock(innerCapStateMutex_);
515 return innerCapStates_;
516 }
517
GetAppInfo()518 AppInfo AudioProcessInServer::GetAppInfo()
519 {
520 return processConfig_.appInfo;
521 }
522
GetConvertedBuffer()523 BufferDesc &AudioProcessInServer::GetConvertedBuffer()
524 {
525 return convertedBuffer_;
526 }
527
Dump(int fd,const std::vector<std::u16string> & args)528 int AudioProcessInServer::Dump(int fd, const std::vector<std::u16string> &args)
529 {
530 return SUCCESS;
531 }
532
Dump(std::string & dumpString)533 void AudioProcessInServer::Dump(std::string &dumpString)
534 {
535 AppendFormat(dumpString, "\n - uid: %d\n", processConfig_.appInfo.appUid);
536 AppendFormat(dumpString, "- pid: %d\n", processConfig_.appInfo.appUid);
537 dumpString += "process info:\n";
538 dumpString += "stream info:\n";
539 AppendFormat(dumpString, " - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
540 AppendFormat(dumpString, " - channels: %d\n", processConfig_.streamInfo.channels);
541 AppendFormat(dumpString, " - format: %d\n", processConfig_.streamInfo.format);
542 AppendFormat(dumpString, " - encoding: %d\n", processConfig_.streamInfo.encoding);
543 if (streamStatus_ != nullptr) {
544 AppendFormat(dumpString, " - Status: %d\n", streamStatus_->load());
545 }
546 dumpString += "\n";
547 }
548
GetStreamBuffer()549 std::shared_ptr<OHAudioBufferBase> AudioProcessInServer::GetStreamBuffer()
550 {
551 CHECK_AND_RETURN_RET_LOG(isBufferConfiged_ && processBuffer_ != nullptr,
552 nullptr, "GetStreamBuffer failed:process buffer not config.");
553 return processBuffer_;
554 }
555
GetStreamInfo()556 AudioStreamInfo AudioProcessInServer::GetStreamInfo()
557 {
558 return processConfig_.streamInfo;
559 }
560
GetAudioSessionId()561 uint32_t AudioProcessInServer::GetAudioSessionId()
562 {
563 return sessionId_;
564 }
565
GetAudioStreamType()566 AudioStreamType AudioProcessInServer::GetAudioStreamType()
567 {
568 return processConfig_.streamType;
569 }
570
GetAudioProcessConfig()571 AudioProcessConfig AudioProcessInServer::GetAudioProcessConfig()
572 {
573 return processConfig_;
574 }
575
PcmFormatToBits(AudioSampleFormat format)576 inline uint32_t PcmFormatToBits(AudioSampleFormat format)
577 {
578 switch (format) {
579 case SAMPLE_U8:
580 return 1; // 1 byte
581 case SAMPLE_S16LE:
582 return 2; // 2 byte
583 case SAMPLE_S24LE:
584 return 3; // 3 byte
585 case SAMPLE_S32LE:
586 return 4; // 4 byte
587 case SAMPLE_F32LE:
588 return 4; // 4 byte
589 default:
590 return 2; // 2 byte
591 }
592 }
593
InitBufferStatus()594 int32_t AudioProcessInServer::InitBufferStatus()
595 {
596 CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_ILLEGAL_STATE,
597 "InitBufferStatus failed, null buffer.");
598
599 processBuffer_->SetLastWrittenTime(ClockTime::GetCurNano());
600 return SUCCESS;
601 }
602
ConfigProcessBuffer(uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,AudioStreamInfo & serverStreamInfo,const std::shared_ptr<OHAudioBufferBase> & buffer)603 int32_t AudioProcessInServer::ConfigProcessBuffer(uint32_t &totalSizeInframe,
604 uint32_t &spanSizeInframe, AudioStreamInfo &serverStreamInfo, const std::shared_ptr<OHAudioBufferBase> &buffer)
605 {
606 if (processBuffer_ != nullptr) {
607 AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
608 return SUCCESS;
609 }
610 // check
611 CHECK_AND_RETURN_RET_LOG(totalSizeInframe != 0 && spanSizeInframe != 0 && totalSizeInframe % spanSizeInframe == 0,
612 ERR_INVALID_PARAM, "ConfigProcessBuffer failed: ERR_INVALID_PARAM");
613
614 uint32_t spanTime = spanSizeInframe * AUDIO_MS_PER_SECOND / serverStreamInfo.samplingRate;
615 spanSizeInframe_ = spanTime * processConfig_.streamInfo.samplingRate / AUDIO_MS_PER_SECOND;
616 totalSizeInframe_ = totalSizeInframe / spanSizeInframe * spanSizeInframe_;
617
618 uint32_t channel = processConfig_.streamInfo.channels;
619 uint32_t formatbyte = PcmFormatToBits(processConfig_.streamInfo.format);
620 byteSizePerFrame_ = channel * formatbyte;
621 if (serverStreamInfo.channels != processConfig_.streamInfo.channels ||
622 serverStreamInfo.format != processConfig_.streamInfo.format) {
623 size_t spanSizeInByte = 0;
624 if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
625 uint32_t serverByteSize = serverStreamInfo.channels * PcmFormatToBits(serverStreamInfo.format);
626 spanSizeInByte = static_cast<size_t>(spanSizeInframe * serverByteSize);
627 } else {
628 spanSizeInByte = static_cast<size_t>(spanSizeInframe_ * byteSizePerFrame_);
629 }
630 convertedBuffer_.buffer = new uint8_t[spanSizeInByte];
631 convertedBuffer_.bufLength = spanSizeInByte;
632 convertedBuffer_.dataLength = spanSizeInByte;
633 }
634
635 if (buffer == nullptr) {
636 // create OHAudioBuffer in server.
637 processBuffer_ = OHAudioBufferBase::CreateFromLocal(totalSizeInframe_, byteSizePerFrame_);
638 CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
639
640 CHECK_AND_RETURN_RET_LOG(processBuffer_->GetBufferHolder() == AudioBufferHolder::AUDIO_SERVER_SHARED,
641 ERR_ILLEGAL_STATE, "CreateFormLocal in server failed.");
642 AUDIO_INFO_LOG("Config: totalSizeInframe:%{public}d spanSizeInframe:%{public}d byteSizePerFrame:%{public}d",
643 totalSizeInframe_, spanSizeInframe_, byteSizePerFrame_);
644
645 // we need to clear data buffer to avoid dirty data.
646 memset_s(processBuffer_->GetDataBase(), processBuffer_->GetDataSize(), 0, processBuffer_->GetDataSize());
647 int32_t ret = InitBufferStatus();
648 AUDIO_DEBUG_LOG("clear data buffer, ret:%{public}d", ret);
649 } else {
650 processBuffer_ = buffer;
651 AUDIO_INFO_LOG("ConfigBuffer in server separate, base: %{public}d", *processBuffer_->GetDataBase());
652 }
653
654 streamStatus_ = processBuffer_->GetStreamStatus();
655 CHECK_AND_RETURN_RET_LOG(streamStatus_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
656 isBufferConfiged_ = true;
657 isInited_ = true;
658 return SUCCESS;
659 }
660
AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)661 int32_t AudioProcessInServer::AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
662 {
663 std::lock_guard<std::mutex> lock(listenerListLock_);
664 listenerList_.push_back(listener);
665 return SUCCESS;
666 }
667
RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)668 int32_t AudioProcessInServer::RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
669 {
670 std::lock_guard<std::mutex> lock(listenerListLock_);
671 std::vector<std::shared_ptr<IProcessStatusListener>>::iterator it = listenerList_.begin();
672 bool isFind = false;
673 while (it != listenerList_.end()) {
674 if (*it == listener) {
675 listenerList_.erase(it);
676 isFind = true;
677 break;
678 } else {
679 it++;
680 }
681 }
682
683 AUDIO_INFO_LOG("%{public}s the endpoint.", (isFind ? "find and remove" : "not find"));
684 return SUCCESS;
685 }
686
RegisterThreadPriority(int32_t tid,const std::string & bundleName,uint32_t method)687 int32_t AudioProcessInServer::RegisterThreadPriority(int32_t tid, const std::string &bundleName, uint32_t method)
688 {
689 pid_t pid = IPCSkeleton::GetCallingPid();
690 CHECK_AND_RETURN_RET_LOG(method < METHOD_MAX, ERR_INVALID_PARAM, "err param %{public}u", method);
691 auto sharedGuard = SharedAudioScheduleGuard::Create(pid, static_cast<pid_t>(tid), bundleName);
692 std::lock_guard lock(scheduleGuardsMutex_);
693 scheduleGuards_[method].swap(sharedGuard);
694 return SUCCESS;
695 }
696
SetAudioHapticsSyncId(int32_t audioHapticsSyncId)697 int32_t AudioProcessInServer::SetAudioHapticsSyncId(int32_t audioHapticsSyncId)
698 {
699 AUDIO_INFO_LOG("AudioProcessInServer::SetAudioHapticsSyncId %{public}d", audioHapticsSyncId);
700 audioHapticsSyncId_.store(audioHapticsSyncId);
701 return SUCCESS;
702 }
703
WriterRenderStreamStandbySysEvent(uint32_t sessionId,int32_t standby)704 void AudioProcessInServer::WriterRenderStreamStandbySysEvent(uint32_t sessionId, int32_t standby)
705 {
706 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
707 Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
708 Media::MediaMonitor::BEHAVIOR_EVENT);
709 bean->Add("STREAMID", static_cast<int32_t>(sessionId));
710 bean->Add("STANDBY", standby);
711 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
712
713 std::unordered_map<std::string, std::string> payload;
714 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
715 payload["sessionId"] = std::to_string(sessionId);
716 payload["isStandby"] = std::to_string(standby);
717 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
718
719 if (playerDfx_ && processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
720 playerDfx_->WriteDfxActionMsg(sessionId_, standby == 0 ?
721 RENDERER_STAGE_STANDBY_END : RENDERER_STAGE_STANDBY_BEGIN);
722 }
723 }
724
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)725 void AudioProcessInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
726 {
727 #ifdef RESSCHE_ENABLE
728 AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
729 ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
730 #endif
731 }
732
WriteDumpFile(void * buffer,size_t bufferSize)733 void AudioProcessInServer::WriteDumpFile(void *buffer, size_t bufferSize)
734 {
735 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
736 DumpFileUtil::WriteDumpFile(dumpFile_, buffer, bufferSize);
737 AudioCacheMgr::GetInstance().CacheData(dumpFileName_, buffer, bufferSize);
738 }
739 }
740
SetDefaultOutputDevice(int32_t defaultOutputDevice,bool skipForce)741 int32_t AudioProcessInServer::SetDefaultOutputDevice(int32_t defaultOutputDevice, bool skipForce)
742 {
743 CHECK_AND_RETURN_RET_LOG(streamStatus_ != nullptr, ERROR, "streamStatus_ is nullptr");
744 return CoreServiceHandler::GetInstance().SetDefaultOutputDevice(static_cast<DeviceType>(defaultOutputDevice),
745 sessionId_, processConfig_.rendererInfo.streamUsage, streamStatus_->load() == STREAM_RUNNING, skipForce);
746 }
747
SetSilentModeAndMixWithOthers(bool on)748 int32_t AudioProcessInServer::SetSilentModeAndMixWithOthers(bool on)
749 {
750 silentModeAndMixWithOthers_ = on;
751 AUDIO_INFO_LOG("%{public}d", on);
752 return SUCCESS;
753 }
754
GetStartMuteTime()755 std::time_t AudioProcessInServer::GetStartMuteTime()
756 {
757 return startMuteTime_;
758 }
759
SetStartMuteTime(std::time_t time)760 void AudioProcessInServer::SetStartMuteTime(std::time_t time)
761 {
762 startMuteTime_ = time;
763 }
764
GetSilentState()765 bool AudioProcessInServer::GetSilentState()
766 {
767 return isInSilentState_;
768 }
769
SetSilentState(bool state)770 void AudioProcessInServer::SetSilentState(bool state)
771 {
772 isInSilentState_ = state;
773 }
SetSourceDuration(int64_t duration)774 int32_t AudioProcessInServer::SetSourceDuration(int64_t duration)
775 {
776 sourceDuration_ = duration;
777 return SUCCESS;
778 }
779
SetUnderrunCount(uint32_t underrunCnt)780 int32_t AudioProcessInServer::SetUnderrunCount(uint32_t underrunCnt)
781 {
782 underrunCount_ = underrunCnt;
783 return SUCCESS;
784 }
785
AddMuteWriteFrameCnt(int64_t muteFrameCnt)786 void AudioProcessInServer::AddMuteWriteFrameCnt(int64_t muteFrameCnt)
787 {
788 lastWriteMuteFrame_ += muteFrameCnt;
789 }
790
AddMuteFrameSize(int64_t muteFrameCnt)791 void AudioProcessInServer::AddMuteFrameSize(int64_t muteFrameCnt)
792 {
793 if (muteFrameCnt < 0) {
794 audioStreamChecker_->RecordMuteFrame();
795 }
796 }
797
AddNoDataFrameSize()798 void AudioProcessInServer::AddNoDataFrameSize()
799 {
800 audioStreamChecker_->RecordNodataFrame();
801 }
802
AddNormalFrameSize()803 void AudioProcessInServer::AddNormalFrameSize()
804 {
805 audioStreamChecker_->RecordNormalFrame();
806 }
807
GetStreamStatus()808 StreamStatus AudioProcessInServer::GetStreamStatus()
809 {
810 return streamStatus_->load();
811 }
812
GetAudioHapticsSyncId()813 int32_t AudioProcessInServer::GetAudioHapticsSyncId()
814 {
815 return audioHapticsSyncId_.load();
816 }
817
GetLastAudioDuration()818 int64_t AudioProcessInServer::GetLastAudioDuration()
819 {
820 auto ret = lastStopTime_ - lastStartTime_;
821 return ret < 0 ? -1 : ret;
822 }
823
RestoreSession(RestoreInfo restoreInfo)824 RestoreStatus AudioProcessInServer::RestoreSession(RestoreInfo restoreInfo)
825 {
826 RestoreStatus restoreStatus = processBuffer_->SetRestoreStatus(NEED_RESTORE);
827 if (restoreStatus == NEED_RESTORE) {
828 if (processConfig_.audioMode == AUDIO_MODE_RECORD) {
829 SwitchStreamInfo info = {
830 sessionId_,
831 processConfig_.callerUid,
832 processConfig_.appInfo.appUid,
833 processConfig_.appInfo.appPid,
834 processConfig_.appInfo.appTokenId,
835 HandleStreamStatusToCapturerState(streamStatus_->load())
836 };
837 AUDIO_INFO_LOG("Insert fast record stream:%{public}u uid:%{public}d tokenId:%{public}u "
838 "into switchStreamRecord because restoreStatus:NEED_RESTORE",
839 sessionId_, info.callerUid, info.appTokenId);
840 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_WAITING);
841 }
842
843 processBuffer_->SetRestoreInfo(restoreInfo);
844 processBuffer_->WakeFutex();
845 }
846 return restoreStatus;
847 }
848
SaveAdjustStreamVolumeInfo(float volume,uint32_t sessionId,const std::string & adjustTime,uint32_t code)849 int32_t AudioProcessInServer::SaveAdjustStreamVolumeInfo(float volume, uint32_t sessionId,
850 const std::string& adjustTime, uint32_t code)
851 {
852 AudioService::GetInstance()->SaveAdjustStreamVolumeInfo(volume, sessionId, adjustTime, code);
853 return SUCCESS;
854 }
855
StopSession()856 int32_t AudioProcessInServer::StopSession()
857 {
858 CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_INVALID_PARAM, "processBuffer_ is nullptr");
859 processBuffer_->SetStopFlag(true);
860 return SUCCESS;
861 }
862
GetSpanSizeInFrame()863 uint32_t AudioProcessInServer::GetSpanSizeInFrame()
864 {
865 return spanSizeInframe_;
866 }
867
GetByteSizePerFrame()868 uint32_t AudioProcessInServer::GetByteSizePerFrame()
869 {
870 return byteSizePerFrame_;
871 }
872 } // namespace AudioStandard
873 } // namespace OHOS
874