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 "CapturerInServer"
17 #endif
18
19 #include "capturer_in_server.h"
20 #include <cinttypes>
21 #include "securec.h"
22 #include "audio_errors.h"
23 #include "audio_utils.h"
24 #include "audio_capturer_log.h"
25 #include "audio_service.h"
26 #include "audio_process_config.h"
27 #include "i_stream_manager.h"
28 #ifdef HAS_FEATURE_INNERCAPTURER
29 #include "playback_capturer_manager.h"
30 #endif
31 #include "policy_handler.h"
32 #include "media_monitor_manager.h"
33 #include "audio_dump_pcm.h"
34 #include "volume_tools.h"
35 #include "core_service_handler.h"
36 #include "stream_dfx_manager.h"
37
38 namespace OHOS {
39 namespace AudioStandard {
40 namespace {
41 static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
42 static const size_t CAPTURER_BUFFER_DEFAULT_NUM = 4;
43 static const size_t CAPTURER_BUFFER_WAKE_UP_NUM = 100;
44 static const uint32_t OVERFLOW_LOG_LOOP_COUNT = 100;
45 constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S
46 }
47
48 enum AudioByteSize : int32_t {
49 BYTE_SIZE_SAMPLE_U8 = 1,
50 BYTE_SIZE_SAMPLE_S16 = 2,
51 BYTE_SIZE_SAMPLE_S24 = 3,
52 BYTE_SIZE_SAMPLE_S32 = 4,
53 };
54
CapturerInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)55 CapturerInServer::CapturerInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
56 {
57 processConfig_ = processConfig;
58 streamListener_ = streamListener;
59 innerCapId_ = processConfig.innerCapId;
60 }
61
~CapturerInServer()62 CapturerInServer::~CapturerInServer()
63 {
64 if (status_ != I_STATUS_RELEASED) {
65 Release();
66 }
67 DumpFileUtil::CloseDumpFile(&dumpS2C_);
68 if (needCheckBackground_) {
69 TurnOffMicIndicator(CAPTURER_INVALID);
70 }
71 }
72
ConfigServerBuffer()73 int32_t CapturerInServer::ConfigServerBuffer()
74 {
75 if (audioServerBuffer_ != nullptr) {
76 AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed.");
77 return SUCCESS;
78 }
79 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "ConfigServerBuffer failed, stream_ is null!");
80 stream_->GetSpanSizePerFrame(spanSizeInFrame_);
81 const size_t bufferNum = ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_WAKEUP)
82 ? CAPTURER_BUFFER_WAKE_UP_NUM : CAPTURER_BUFFER_DEFAULT_NUM);
83 totalSizeInFrame_ = spanSizeInFrame_ * bufferNum;
84 stream_->GetByteSizePerFrame(byteSizePerFrame_);
85 spanSizeInBytes_ = byteSizePerFrame_ * spanSizeInFrame_;
86 AUDIO_INFO_LOG("ConfigProcessBuffer: totalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu,"
87 "byteSizePerFrame_: %{public}zu, spanSizeInBytes_ %{public}zu", totalSizeInFrame_, spanSizeInFrame_,
88 byteSizePerFrame_, spanSizeInBytes_);
89 if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) {
90 AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
91 return ERR_INVALID_PARAM;
92 }
93
94 int32_t ret = InitCacheBuffer(2 * spanSizeInBytes_);
95 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitCacheBuffer failed %{public}d", ret);
96
97 // create OHAudioBuffer in server
98 audioServerBuffer_ = OHAudioBuffer::CreateFromLocal(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_);
99 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
100
101 // we need to clear data buffer to avoid dirty data.
102 memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
103 audioServerBuffer_->GetDataSize());
104 ret = InitBufferStatus();
105 AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
106 isBufferConfiged_ = true;
107 isInited_ = true;
108 return SUCCESS;
109 }
110
InitBufferStatus()111 int32_t CapturerInServer::InitBufferStatus()
112 {
113 if (audioServerBuffer_ == nullptr) {
114 AUDIO_ERR_LOG("InitBufferStatus failed, null buffer!");
115 return ERR_ILLEGAL_STATE;
116 }
117
118 uint32_t spanCount = audioServerBuffer_->GetSpanCount();
119 AUDIO_INFO_LOG("InitBufferStatus: spanCount %{public}u", spanCount);
120 for (uint32_t i = 0; i < spanCount; i++) {
121 SpanInfo *spanInfo = audioServerBuffer_->GetSpanInfoByIndex(i);
122 if (spanInfo == nullptr) {
123 AUDIO_ERR_LOG("InitBufferStatus failed, null spaninfo");
124 return ERR_ILLEGAL_STATE;
125 }
126 spanInfo->spanStatus = SPAN_READ_DONE;
127 spanInfo->offsetInFrame = 0;
128
129 spanInfo->readStartTime = 0;
130 spanInfo->readDoneTime = 0;
131
132 spanInfo->readStartTime = 0;
133 spanInfo->readDoneTime = 0;
134
135 spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
136 spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
137 spanInfo->isMute = false;
138 }
139 return SUCCESS;
140 }
141
Init()142 int32_t CapturerInServer::Init()
143 {
144 int32_t ret = IStreamManager::GetRecorderManager().CreateCapturer(processConfig_, stream_);
145 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
146 "Construct CapturerInServer failed: %{public}d", ret);
147 streamIndex_ = stream_->GetStreamIndex();
148 capturerClock_ = CapturerClockManager::GetInstance().CreateCapturerClock(
149 streamIndex_, processConfig_.streamInfo.samplingRate);
150 ret = ConfigServerBuffer();
151 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "ConfigServerBuffer failed: %{public}d", ret);
152 stream_->RegisterStatusCallback(shared_from_this());
153 stream_->RegisterReadCallback(shared_from_this());
154
155 traceTag_ = "[" + std::to_string(streamIndex_) + "]CapturerServerOut"; // [100001]CapturerServerOut
156 // eg: /data/data/.pulse_dir/10000_100009_capturer_server_out_48000_2_1.pcm
157 AudioStreamInfo tempInfo = processConfig_.streamInfo;
158 dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
159 + "_capturer_server_out_" + std::to_string(tempInfo.samplingRate) + "_"
160 + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
161 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpS2C_);
162 recorderDfx_ = std::make_unique<RecorderDfxWriter>(processConfig_.appInfo, streamIndex_);
163 AudioService::GetInstance()->RegisterMuteStateChangeCallback(streamIndex_, [this](bool flag) {
164 AUDIO_INFO_LOG("recv mute state change flag %{public}d", flag ? 1 : 0);
165 muteFlag_ = flag;
166 });
167
168 return SUCCESS;
169 }
170
OnStatusUpdate(IOperation operation)171 void CapturerInServer::OnStatusUpdate(IOperation operation)
172 {
173 AUDIO_INFO_LOG("CapturerInServer::OnStatusUpdate operation: %{public}d", operation);
174 operation_ = operation;
175 if (status_ == I_STATUS_RELEASED) {
176 AUDIO_WARNING_LOG("Stream already released");
177 return;
178 }
179 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
180 CHECK_AND_RETURN_LOG((stateListener != nullptr && recorderDfx_ != nullptr), "IStreamListener is nullptr");
181 switch (operation) {
182 case OPERATION_UNDERFLOW:
183 underflowCount += 1;
184 AUDIO_INFO_LOG("Underflow!! underflow count %{public}d", underflowCount);
185 stateListener->OnOperationHandled(BUFFER_OVERFLOW, underflowCount);
186 break;
187 case OPERATION_STARTED:
188 status_ = I_STATUS_STARTED;
189 lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
190 std::chrono::system_clock::now().time_since_epoch()).count();
191 stateListener->OnOperationHandled(START_STREAM, 0);
192 break;
193 case OPERATION_PAUSED:
194 status_ = I_STATUS_PAUSED;
195 stateListener->OnOperationHandled(PAUSE_STREAM, 0);
196 HandleOperationStopped(CAPTURER_STAGE_PAUSE_OK);
197 break;
198 case OPERATION_STOPPED:
199 status_ = I_STATUS_STOPPED;
200 stateListener->OnOperationHandled(STOP_STREAM, 0);
201 HandleOperationStopped(CAPTURER_STAGE_STOP_OK);
202 break;
203 case OPERATION_FLUSHED:
204 HandleOperationFlushed();
205 stateListener->OnOperationHandled(FLUSH_STREAM, 0);
206 break;
207 default:
208 AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
209 status_ = I_STATUS_INVALID;
210 }
211
212 CaptureConcurrentCheck(streamIndex_);
213 }
214
HandleOperationFlushed()215 void CapturerInServer::HandleOperationFlushed()
216 {
217 if (status_ == I_STATUS_FLUSHING_WHEN_STARTED) {
218 status_ = I_STATUS_STARTED;
219 } else if (status_ == I_STATUS_FLUSHING_WHEN_PAUSED) {
220 status_ = I_STATUS_PAUSED;
221 } else if (status_ == I_STATUS_FLUSHING_WHEN_STOPPED) {
222 status_ = I_STATUS_STOPPED;
223 } else {
224 AUDIO_WARNING_LOG("Invalid status before flusing");
225 }
226 }
227
HandleOperationStopped(CapturerStage stage)228 void CapturerInServer::HandleOperationStopped(CapturerStage stage)
229 {
230 CHECK_AND_RETURN_LOG(recorderDfx_ != nullptr, "nullptr");
231 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
232 std::chrono::system_clock::now().time_since_epoch()).count();
233 recorderDfx_->WriteDfxStopMsg(streamIndex_, stage,
234 GetLastAudioDuration(), processConfig_);
235 }
236
DequeueBuffer(size_t length)237 BufferDesc CapturerInServer::DequeueBuffer(size_t length)
238 {
239 return stream_->DequeueBuffer(length);
240 }
241
IsReadDataOverFlow(size_t length,uint64_t currentWriteFrame,std::shared_ptr<IStreamListener> stateListener)242 bool CapturerInServer::IsReadDataOverFlow(size_t length, uint64_t currentWriteFrame,
243 std::shared_ptr<IStreamListener> stateListener)
244 {
245 if (audioServerBuffer_->GetWritableDataFrames() <= static_cast<int32_t>(spanSizeInFrame_)) {
246 if (overFlowLogFlag_ == 0) {
247 AUDIO_INFO_LOG("OverFlow!!!");
248 } else if (overFlowLogFlag_ == OVERFLOW_LOG_LOOP_COUNT) {
249 overFlowLogFlag_ = 0;
250 }
251 overFlowLogFlag_++;
252 int32_t engineFlag = GetEngineFlag();
253 if (engineFlag != 1) {
254 BufferDesc dstBuffer = stream_->DequeueBuffer(length);
255 stream_->EnqueueBuffer(dstBuffer);
256 }
257 stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame);
258 return true;
259 }
260 return false;
261 }
262
263
HandleStreamStatusToCapturerState(const IStatus & status)264 static CapturerState HandleStreamStatusToCapturerState(const IStatus &status)
265 {
266 switch (status) {
267 case I_STATUS_IDLE:
268 return CAPTURER_PREPARED;
269 case I_STATUS_STARTING:
270 case I_STATUS_STARTED:
271 case I_STATUS_FLUSHING_WHEN_STARTED:
272 return CAPTURER_RUNNING;
273 case I_STATUS_PAUSING:
274 case I_STATUS_PAUSED:
275 case I_STATUS_FLUSHING_WHEN_PAUSED:
276 return CAPTURER_PAUSED;
277 case I_STATUS_STOPPING:
278 case I_STATUS_STOPPED:
279 case I_STATUS_FLUSHING_WHEN_STOPPED:
280 return CAPTURER_STOPPED;
281 case I_STATUS_RELEASING:
282 case I_STATUS_RELEASED:
283 return CAPTURER_RELEASED;
284 default:
285 return CAPTURER_INVALID;
286 }
287 }
288
GetByteSizeByFormat(enum AudioSampleFormat format)289 static uint32_t GetByteSizeByFormat(enum AudioSampleFormat format)
290 {
291 uint32_t byteSize = 0;
292 switch (format) {
293 case AudioSampleFormat::SAMPLE_U8:
294 byteSize = BYTE_SIZE_SAMPLE_U8;
295 break;
296 case AudioSampleFormat::SAMPLE_S16LE:
297 byteSize = BYTE_SIZE_SAMPLE_S16;
298 break;
299 case AudioSampleFormat::SAMPLE_S24LE:
300 byteSize = BYTE_SIZE_SAMPLE_S24;
301 break;
302 case AudioSampleFormat::SAMPLE_S32LE:
303 byteSize = BYTE_SIZE_SAMPLE_S32;
304 break;
305 case AudioSampleFormat::SAMPLE_F32LE:
306 byteSize = BYTE_SIZE_SAMPLE_S32;
307 break;
308 default:
309 byteSize = BYTE_SIZE_SAMPLE_S16;
310 break;
311 }
312 return byteSize;
313 }
314
UpdateBufferTimeStamp(size_t readLen)315 void CapturerInServer::UpdateBufferTimeStamp(size_t readLen)
316 {
317 CHECK_AND_RETURN_LOG(capturerClock_ != nullptr, "capturerClock_ is nullptr!");
318 uint64_t timestamp = 0;
319 uint32_t sizePerPos = static_cast<uint32_t>(GetByteSizeByFormat(processConfig_.streamInfo.format)) *
320 processConfig_.streamInfo.channels;
321
322 curProcessPos_ += lastPosInc_;
323 CHECK_AND_RETURN_LOG(readLen >= 0, "readLen is illegal!");
324 lastPosInc_ = static_cast<uint64_t>(readLen) / sizePerPos;
325
326 capturerClock_->GetTimeStampByPosition(curProcessPos_, timestamp);
327
328 AUDIO_DEBUG_LOG("update buffer timestamp pos:%{public}" PRIu64 " ts:%{public}" PRIu64,
329 curProcessPos_, timestamp);
330 audioServerBuffer_->SetTimeStampInfo(curProcessPos_, timestamp);
331 }
332
ReadData(size_t length)333 void CapturerInServer::ReadData(size_t length)
334 {
335 CHECK_AND_RETURN_LOG(length >= spanSizeInBytes_,
336 "Length %{public}zu is less than spanSizeInBytes %{public}zu", length, spanSizeInBytes_);
337 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
338 CHECK_AND_RETURN_LOG(stateListener != nullptr, "IStreamListener is nullptr!");
339 CHECK_AND_RETURN_LOG(stream_ != nullptr, "ReadData failed, stream_ is null!");
340
341 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
342 if (IsReadDataOverFlow(length, currentWriteFrame, stateListener)) {
343 UpdateBufferTimeStamp(length);
344 return;
345 }
346 Trace trace(traceTag_ + "::ReadData:" + std::to_string(currentWriteFrame));
347 OptResult result = ringCache_->GetWritableSize();
348 CHECK_AND_RETURN_LOG(result.ret == OPERATION_SUCCESS, "RingCache write invalid size %{public}zu", result.size);
349 BufferDesc srcBuffer = stream_->DequeueBuffer(result.size);
350 ringCache_->Enqueue({srcBuffer.buffer, srcBuffer.bufLength});
351 result = ringCache_->GetReadableSize();
352 if (result.ret != OPERATION_SUCCESS || result.size < spanSizeInBytes_) {
353 stream_->EnqueueBuffer(srcBuffer);
354 return;
355 }
356
357 BufferDesc dstBuffer = {nullptr, 0, 0};
358
359 uint64_t curWritePos = audioServerBuffer_->GetCurWriteFrame();
360 if (audioServerBuffer_->GetWriteBuffer(curWritePos, dstBuffer) < 0) {
361 return;
362 }
363
364 if ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode ==
365 LEGACY_MUTE_CAP) || muteFlag_) {
366 dstBuffer.buffer = dischargeBuffer_.get(); // discharge valid data.
367 }
368 if (muteFlag_) {
369 memset_s(static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength, 0, dstBuffer.bufLength);
370 }
371 ringCache_->Dequeue({dstBuffer.buffer, dstBuffer.bufLength});
372 VolumeTools::DfxOperation(dstBuffer, processConfig_.streamInfo, traceTag_, volumeDataCount_);
373 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
374 DumpFileUtil::WriteDumpFile(dumpS2C_, static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
375 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
376 static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
377 }
378
379 uint64_t nextWriteFrame = currentWriteFrame + spanSizeInFrame_;
380 audioServerBuffer_->SetCurWriteFrame(nextWriteFrame);
381 audioServerBuffer_->SetHandleInfo(currentWriteFrame, ClockTime::GetCurNano());
382
383 UpdateBufferTimeStamp(dstBuffer.bufLength);
384
385 stream_->EnqueueBuffer(srcBuffer);
386 stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame);
387 }
388
OnReadData(size_t length)389 int32_t CapturerInServer::OnReadData(size_t length)
390 {
391 Trace trace(traceTag_ + "::OnReadData:" + std::to_string(length));
392 ReadData(length);
393 return SUCCESS;
394 }
395
OnReadData(int8_t * outputData,size_t requestDataLen)396 int32_t CapturerInServer::OnReadData(int8_t *outputData, size_t requestDataLen)
397 {
398 CHECK_AND_RETURN_RET_LOG(status_.load() == I_STATUS_STARTED, ERR_READ_FAILED, "CapturerInServer is not started");
399 CHECK_AND_RETURN_RET_LOG(requestDataLen >= spanSizeInBytes_, ERR_READ_FAILED,
400 "Length %{public}zu is less than spanSizeInBytes %{public}zu", requestDataLen, spanSizeInBytes_);
401 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
402 CHECK_AND_RETURN_RET_LOG(stateListener != nullptr, ERR_READ_FAILED, "IStreamListener is nullptr!");
403 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
404 if (IsReadDataOverFlow(requestDataLen, currentWriteFrame, stateListener)) {
405 UpdateBufferTimeStamp(requestDataLen);
406 return ERR_WRITE_FAILED;
407 }
408 Trace trace("CapturerInServer::ReadData:" + std::to_string(currentWriteFrame));
409 OptResult result = ringCache_->GetWritableSize();
410 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_READ_FAILED,
411 "RingCache write invalid size %{public}zu", result.size);
412
413 BufferDesc srcBuffer = {reinterpret_cast<uint8_t *>(outputData), requestDataLen, 0};
414
415 ringCache_->Enqueue({srcBuffer.buffer, srcBuffer.bufLength});
416 result = ringCache_->GetReadableSize();
417 if (result.ret != OPERATION_SUCCESS || result.size < spanSizeInBytes_) {
418 return SUCCESS;
419 }
420
421 BufferDesc dstBuffer = {nullptr, 0, 0};
422 uint64_t curWritePos = audioServerBuffer_->GetCurWriteFrame();
423 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetWriteBuffer(curWritePos, dstBuffer) >= 0, ERR_READ_FAILED,
424 "GetWriteBuffer failed");
425 if ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode ==
426 LEGACY_MUTE_CAP) || muteFlag_) {
427 dstBuffer.buffer = dischargeBuffer_.get(); // discharge valid data.
428 }
429 if (muteFlag_) {
430 memset_s(static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength, 0, dstBuffer.bufLength);
431 }
432 ringCache_->Dequeue({dstBuffer.buffer, dstBuffer.bufLength});
433 VolumeTools::DfxOperation(dstBuffer, processConfig_.streamInfo, traceTag_, volumeDataCount_);
434 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
435 DumpFileUtil::WriteDumpFile(dumpS2C_, static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
436 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
437 static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
438 }
439
440 uint64_t nextWriteFrame = currentWriteFrame + spanSizeInFrame_;
441 audioServerBuffer_->SetCurWriteFrame(nextWriteFrame);
442 audioServerBuffer_->SetHandleInfo(currentWriteFrame, ClockTime::GetCurNano());
443
444 UpdateBufferTimeStamp(dstBuffer.bufLength);
445
446 stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame);
447
448 return SUCCESS;
449 }
450
UpdateReadIndex()451 int32_t CapturerInServer::UpdateReadIndex()
452 {
453 AUDIO_DEBUG_LOG("audioServerBuffer_->GetWritableDataFrames(): %{public}d, needStart: %{public}d",
454 audioServerBuffer_->GetWritableDataFrames(), needStart);
455 return SUCCESS;
456 }
457
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)458 int32_t CapturerInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
459 {
460 buffer = audioServerBuffer_;
461 return SUCCESS;
462 }
463
GetSessionId(uint32_t & sessionId)464 int32_t CapturerInServer::GetSessionId(uint32_t &sessionId)
465 {
466 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
467 sessionId = streamIndex_;
468 CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
469 sessionId);
470
471 return SUCCESS;
472 }
473
CheckBGCapture()474 bool CapturerInServer::CheckBGCapture()
475 {
476 uint32_t tokenId = processConfig_.appInfo.appTokenId;
477 uint64_t fullTokenId = processConfig_.appInfo.appFullTokenId;
478
479 if (PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId)) {
480 return true;
481 }
482
483 CHECK_AND_RETURN_RET_LOG(processConfig_.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION &&
484 AudioService::GetInstance()->InForegroundList(processConfig_.appInfo.appUid), false, "Check failed");
485
486 AudioService::GetInstance()->UpdateForegroundState(tokenId, true);
487 bool res = PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId);
488 AUDIO_INFO_LOG("Retry result:%{public}s", (res ? "success" : "fail"));
489 AudioService::GetInstance()->UpdateForegroundState(tokenId, false);
490
491 return res;
492 }
493
TurnOnMicIndicator(CapturerState capturerState)494 bool CapturerInServer::TurnOnMicIndicator(CapturerState capturerState)
495 {
496 uint32_t tokenId = processConfig_.appInfo.appTokenId;
497 SwitchStreamInfo info = {
498 streamIndex_,
499 processConfig_.callerUid,
500 processConfig_.appInfo.appUid,
501 processConfig_.appInfo.appPid,
502 tokenId,
503 capturerState,
504 };
505 if (!SwitchStreamUtil::IsSwitchStreamSwitching(info, SWITCH_STATE_STARTED)) {
506 CHECK_AND_RETURN_RET_LOG(CheckBGCapture(), false, "Verify failed");
507 }
508 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_STARTED);
509
510 if (isMicIndicatorOn_) {
511 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already on."
512 "No need to call NotifyPrivacyStart!", streamIndex_);
513 } else {
514 CHECK_AND_RETURN_RET_LOG(PermissionUtil::NotifyPrivacyStart(tokenId, streamIndex_),
515 false, "NotifyPrivacyStart failed!");
516 AUDIO_INFO_LOG("Turn on micIndicator of stream:%{public}d from off "
517 "after NotifyPrivacyStart success!", streamIndex_);
518 isMicIndicatorOn_ = true;
519 }
520 return true;
521 }
522
TurnOffMicIndicator(CapturerState capturerState)523 bool CapturerInServer::TurnOffMicIndicator(CapturerState capturerState)
524 {
525 uint32_t tokenId = processConfig_.appInfo.appTokenId;
526 SwitchStreamInfo info = {
527 streamIndex_,
528 processConfig_.callerUid,
529 processConfig_.appInfo.appUid,
530 processConfig_.appInfo.appPid,
531 tokenId,
532 capturerState,
533 };
534 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_FINISHED);
535
536 if (isMicIndicatorOn_) {
537 PermissionUtil::NotifyPrivacyStop(tokenId, streamIndex_);
538 AUDIO_INFO_LOG("Turn off micIndicator of stream:%{public}d from on after NotifyPrivacyStop!", streamIndex_);
539 isMicIndicatorOn_ = false;
540 } else {
541 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already off."
542 "No need to call NotifyPrivacyStop!", streamIndex_);
543 }
544 return true;
545 }
546
Start()547 int32_t CapturerInServer::Start()
548 {
549 AudioXCollie audioXCollie(
550 "CapturerInServer::Start", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
551 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
552 int32_t ret = StartInner();
553 CapturerStage stage = ret == SUCCESS ? CAPTURER_STAGE_START_OK : CAPTURER_STAGE_START_FAIL;
554 if (recorderDfx_) {
555 recorderDfx_->WriteDfxStartMsg(streamIndex_, stage, processConfig_);
556 }
557 if (ret == SUCCESS) {
558 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, true);
559 }
560 return ret;
561 }
562
StartInner()563 int32_t CapturerInServer::StartInner()
564 {
565 needStart = 0;
566 std::unique_lock<std::mutex> lock(statusLock_);
567
568 if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
569 AUDIO_ERR_LOG("CapturerInServer::Start failed, Illegal state: %{public}u", status_.load());
570 return ERR_ILLEGAL_STATE;
571 }
572
573 if (!needCheckBackground_ && PermissionUtil::NeedVerifyBackgroundCapture(processConfig_.callerUid,
574 processConfig_.capturerInfo.sourceType)) {
575 AUDIO_INFO_LOG("set needCheckBackground_: true");
576 needCheckBackground_ = true;
577 }
578 if (needCheckBackground_) {
579 CHECK_AND_RETURN_RET_LOG(TurnOnMicIndicator(CAPTURER_RUNNING), ERR_PERMISSION_DENIED,
580 "Turn on micIndicator failed or check backgroud capture failed for stream:%{public}d!", streamIndex_);
581 }
582
583 if (processConfig_.capturerInfo.sourceType != SOURCE_TYPE_PLAYBACK_CAPTURE) {
584 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_START);
585 }
586
587 if (CoreServiceHandler::GetInstance().ReloadCaptureSession(streamIndex_, SESSION_OPERATION_START) == SUCCESS) {
588 AUDIO_ERR_LOG("ReloadCaptureSession success!");
589 }
590
591 status_ = I_STATUS_STARTING;
592 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
593 PlaybackCapturerManager::GetInstance()->InitAllDupBuffer(innerCapId_);
594 }
595 int32_t ret = stream_->Start();
596 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
597 resetTime_ = true;
598
599 if (capturerClock_ != nullptr) {
600 capturerClock_->Start();
601 }
602
603 return SUCCESS;
604 }
605
Pause()606 int32_t CapturerInServer::Pause()
607 {
608 AudioXCollie audioXCollie(
609 "CapturerInServer::Pause", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
610 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
611 std::unique_lock<std::mutex> lock(statusLock_);
612
613 if (status_ != I_STATUS_STARTED) {
614 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
615 return ERR_ILLEGAL_STATE;
616 }
617 if (needCheckBackground_) {
618 TurnOffMicIndicator(CAPTURER_PAUSED);
619 }
620 if (CoreServiceHandler::GetInstance().ReloadCaptureSession(streamIndex_, SESSION_OPERATION_PAUSE) == SUCCESS) {
621 AUDIO_INFO_LOG("ReloadCaptureSession success!");
622 }
623
624 status_ = I_STATUS_PAUSING;
625 int ret = stream_->Pause();
626 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
627 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_PAUSE);
628 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
629 if (capturerClock_ != nullptr) {
630 capturerClock_->Stop();
631 }
632 return SUCCESS;
633 }
634
Flush()635 int32_t CapturerInServer::Flush()
636 {
637 AudioXCollie audioXCollie(
638 "CapturerInServer::Flush", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
639 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
640 std::unique_lock<std::mutex> lock(statusLock_);
641 if (status_ == I_STATUS_STARTED) {
642 status_ = I_STATUS_FLUSHING_WHEN_STARTED;
643 } else if (status_ == I_STATUS_PAUSED) {
644 status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
645 } else if (status_ == I_STATUS_STOPPED) {
646 status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
647 } else {
648 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
649 return ERR_ILLEGAL_STATE;
650 }
651
652 // Flush buffer of audio server
653 uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
654 uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
655
656 while (readFrame < writeFrame) {
657 BufferDesc bufferDesc = {nullptr, 0, 0};
658 int32_t readResult = audioServerBuffer_->GetReadbuffer(readFrame, bufferDesc);
659 if (readResult != 0) {
660 return ERR_OPERATION_FAILED;
661 }
662 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
663 readFrame += spanSizeInFrame_;
664 AUDIO_INFO_LOG("On flush, write frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
665 "readFrame: %{public}" PRIu64 "", writeFrame, spanSizeInFrame_, readFrame);
666 audioServerBuffer_->SetCurReadFrame(readFrame);
667 }
668
669 int ret = stream_->Flush();
670 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
671 return SUCCESS;
672 }
673
DrainAudioBuffer()674 int32_t CapturerInServer::DrainAudioBuffer()
675 {
676 return SUCCESS;
677 }
678
Stop()679 int32_t CapturerInServer::Stop()
680 {
681 AudioXCollie audioXCollie(
682 "CapturerInServer::Stop", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
683 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
684 std::unique_lock<std::mutex> lock(statusLock_);
685 if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED) {
686 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
687 return ERR_ILLEGAL_STATE;
688 }
689 status_ = I_STATUS_STOPPING;
690
691 if (capturerClock_ != nullptr) {
692 capturerClock_->Stop();
693 }
694 if (needCheckBackground_) {
695 TurnOffMicIndicator(CAPTURER_STOPPED);
696 }
697 if (CoreServiceHandler::GetInstance().ReloadCaptureSession(streamIndex_, SESSION_OPERATION_STOP) == SUCCESS) {
698 AUDIO_INFO_LOG("ReloadCaptureSession success!");
699 }
700
701 int ret = stream_->Stop();
702 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
703 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_STOP);
704 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
705 return SUCCESS;
706 }
707
Release(bool isSwitchStream)708 int32_t CapturerInServer::Release(bool isSwitchStream)
709 {
710 AudioXCollie audioXCollie("CapturerInServer::Release", RELEASE_TIMEOUT_IN_SEC,
711 nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
712 AudioService::GetInstance()->RemoveCapturer(streamIndex_, isSwitchStream);
713 std::unique_lock<std::mutex> lock(statusLock_);
714 if (status_ == I_STATUS_RELEASED) {
715 AUDIO_INFO_LOG("Already released");
716 return SUCCESS;
717 }
718 lock.unlock();
719 AUDIO_INFO_LOG("Start release capturer");
720
721 if (processConfig_.capturerInfo.sourceType != SOURCE_TYPE_PLAYBACK_CAPTURE) {
722 int32_t result =
723 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_RELEASE);
724 CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "Policy remove client failed, reason: %{public}d", result);
725 }
726 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
727 int32_t ret = IStreamManager::GetRecorderManager().ReleaseCapturer(streamIndex_);
728 if (ret < 0) {
729 AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
730 status_ = I_STATUS_INVALID;
731 return ret;
732 }
733 if (status_ != I_STATUS_STOPPING &&
734 status_ != I_STATUS_STOPPED) {
735 HandleOperationStopped(CAPTURER_STAGE_STOP_BY_RELEASE);
736 }
737 if (CoreServiceHandler::GetInstance().ReloadCaptureSession(streamIndex_, SESSION_OPERATION_RELEASE) == SUCCESS) {
738 AUDIO_INFO_LOG("ReloadCaptureSession success!");
739 }
740 status_ = I_STATUS_RELEASED;
741
742 capturerClock_ = nullptr;
743 CapturerClockManager::GetInstance().DeleteCapturerClock(streamIndex_);
744 #ifdef HAS_FEATURE_INNERCAPTURER
745 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
746 AUDIO_INFO_LOG("Disable inner capturer for %{public}u, innerCapId :%{public}d, innerCapMode:%{public}d",
747 streamIndex_, innerCapId_, processConfig_.innerCapMode);
748 if (processConfig_.innerCapMode == MODERN_INNER_CAP) {
749 PlaybackCapturerManager::GetInstance()->RemovePlaybackCapturerFilterInfo(streamIndex_, innerCapId_);
750 } else {
751 PlaybackCapturerManager::GetInstance()->SetInnerCapturerState(false);
752 }
753 if (PlaybackCapturerManager::GetInstance()->CheckReleaseUnloadModernInnerCapSink(innerCapId_)) {
754 AudioService::GetInstance()->UnloadModernInnerCapSink(innerCapId_);
755 }
756 innerCapId_ = 0;
757 }
758 #endif
759 if (needCheckBackground_) {
760 TurnOffMicIndicator(CAPTURER_RELEASED);
761 }
762 return SUCCESS;
763 }
764
765 #ifdef HAS_FEATURE_INNERCAPTURER
UpdatePlaybackCaptureConfigInLegacy(const AudioPlaybackCaptureConfig & config)766 int32_t CapturerInServer::UpdatePlaybackCaptureConfigInLegacy(const AudioPlaybackCaptureConfig &config)
767 {
768 Trace trace("UpdatePlaybackCaptureConfigInLegacy");
769 // Legacy mode, only usage filter works.
770 AUDIO_INFO_LOG("Update config in legacy mode with %{public}zu usage", config.filterOptions.usages.size());
771
772 std::vector<int32_t> usage;
773 for (size_t i = 0; i < config.filterOptions.usages.size(); i++) {
774 usage.push_back(config.filterOptions.usages[i]);
775 }
776
777 PlaybackCapturerManager::GetInstance()->SetSupportStreamUsage(usage);
778 PlaybackCapturerManager::GetInstance()->SetInnerCapturerState(true);
779 return SUCCESS;
780 }
781
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)782 int32_t CapturerInServer::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
783 {
784 Trace trace("UpdatePlaybackCaptureConfig:" + ProcessConfig::DumpInnerCapConfig(config));
785 CHECK_AND_RETURN_RET_LOG(processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE,
786 ERR_INVALID_OPERATION, "This not a inner-cap source!");
787
788 AUDIO_INFO_LOG("Client using config: %{public}s", ProcessConfig::DumpInnerCapConfig(config).c_str());
789
790 for (auto &usg : config.filterOptions.usages) {
791 if (usg != STREAM_USAGE_VOICE_COMMUNICATION) {
792 continue;
793 }
794
795 if (!PermissionUtil::VerifyPermission(CAPTURER_VOICE_DOWNLINK_PERMISSION, processConfig_.appInfo.appTokenId)) {
796 AUDIO_ERR_LOG("downlink capturer permission check failed");
797 return ERR_PERMISSION_DENIED;
798 }
799 }
800 filterConfig_ = config;
801
802 if (filterConfig_.filterOptions.usages.size() == 0) {
803 std::vector<StreamUsage> defalutUsages = PlaybackCapturerManager::GetInstance()->GetDefaultUsages();
804 for (size_t i = 0; i < defalutUsages.size(); i++) {
805 filterConfig_.filterOptions.usages.push_back(defalutUsages[i]);
806 }
807 AUDIO_INFO_LOG("Reset config to %{public}s", ProcessConfig::DumpInnerCapConfig(filterConfig_).c_str());
808 }
809
810 if (processConfig_.innerCapMode != MODERN_INNER_CAP) {
811 return UpdatePlaybackCaptureConfigInLegacy(filterConfig_);
812 }
813
814 // in plan: add more check and print config
815 PlaybackCapturerManager::GetInstance()->SetPlaybackCapturerFilterInfo(streamIndex_, filterConfig_, innerCapId_);
816 return SUCCESS;
817 }
818 #endif
819
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)820 int32_t CapturerInServer::GetAudioTime(uint64_t &framePos, uint64_t ×tamp)
821 {
822 if (status_ == I_STATUS_STOPPED) {
823 AUDIO_WARNING_LOG("Current status is stopped");
824 return ERR_ILLEGAL_STATE;
825 }
826 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetAudioTime failed, stream_ is null");
827 stream_->GetStreamFramesRead(framePos);
828 stream_->GetCurrentTimeStamp(timestamp);
829 if (resetTime_) {
830 resetTime_ = false;
831 resetTimestamp_ = timestamp;
832 }
833 return SUCCESS;
834 }
835
GetLatency(uint64_t & latency)836 int32_t CapturerInServer::GetLatency(uint64_t &latency)
837 {
838 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetLatency failed, stream_ is null");
839 return stream_->GetLatency(latency);
840 }
841
InitCacheBuffer(size_t targetSize)842 int32_t CapturerInServer::InitCacheBuffer(size_t targetSize)
843 {
844 CHECK_AND_RETURN_RET_LOG(spanSizeInBytes_ != 0, ERR_OPERATION_FAILED, "spanSizeInByte_ invalid");
845
846 AUDIO_INFO_LOG("old size:%{public}zu, new size:%{public}zu", cacheSizeInBytes_, targetSize);
847 cacheSizeInBytes_ = targetSize;
848
849 if (ringCache_ == nullptr) {
850 ringCache_ = AudioRingCache::Create(cacheSizeInBytes_);
851 } else {
852 OptResult result = ringCache_->ReConfig(cacheSizeInBytes_, false); // false --> clear buffer
853 if (result.ret != OPERATION_SUCCESS) {
854 AUDIO_ERR_LOG("ReConfig AudioRingCache to size %{public}u failed:ret%{public}zu", result.ret, targetSize);
855 return ERR_OPERATION_FAILED;
856 }
857 }
858
859 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode ==
860 LEGACY_MUTE_CAP) {
861 dischargeBuffer_ = std::make_unique<uint8_t []>(cacheSizeInBytes_);
862 }
863
864 return SUCCESS;
865 }
866
SetNonInterruptMute(const bool muteFlag)867 void CapturerInServer::SetNonInterruptMute(const bool muteFlag)
868 {
869 AUDIO_INFO_LOG("muteFlag: %{public}d", muteFlag);
870 muteFlag_ = muteFlag;
871 AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
872 }
873
RestoreSession(RestoreInfo restoreInfo)874 RestoreStatus CapturerInServer::RestoreSession(RestoreInfo restoreInfo)
875 {
876 RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
877 if (restoreStatus == NEED_RESTORE) {
878 SwitchStreamInfo info = {
879 streamIndex_,
880 processConfig_.callerUid,
881 processConfig_.appInfo.appUid,
882 processConfig_.appInfo.appPid,
883 processConfig_.appInfo.appTokenId,
884 HandleStreamStatusToCapturerState(status_)
885 };
886 AUDIO_INFO_LOG("Insert fast record stream:%{public}u uid:%{public}d tokenId:%{public}u "
887 "into switchStreamRecord because restoreStatus:NEED_RESTORE",
888 streamIndex_, info.callerUid, info.appTokenId);
889 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_WAITING);
890
891 audioServerBuffer_->SetRestoreInfo(restoreInfo);
892 }
893 return restoreStatus;
894 }
895
GetLastAudioDuration()896 int64_t CapturerInServer::GetLastAudioDuration()
897 {
898 auto ret = lastStopTime_ - lastStartTime_;
899 return ret < 0 ? -1 : ret;
900 }
901
StopSession()902 int32_t CapturerInServer::StopSession()
903 {
904 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_INVALID_PARAM, "audioServerBuffer_ is nullptr");
905 audioServerBuffer_->SetStopFlag(true);
906 return SUCCESS;
907 }
908
ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> & buffer,uint32_t & spanSizeInFrame,uint64_t & engineTotalSizeInFrame)909 int32_t CapturerInServer::ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> &buffer,
910 uint32_t &spanSizeInFrame, uint64_t &engineTotalSizeInFrame)
911 {
912 return ERR_NOT_SUPPORTED;
913 }
914
CaptureConcurrentCheck(uint32_t streamIndex)915 inline void CapturerInServer::CaptureConcurrentCheck(uint32_t streamIndex)
916 {
917 if (lastStatus_ == status_) {
918 return;
919 }
920 std::atomic_store(&lastStatus_, status_);
921 int32_t ret = PolicyHandler::GetInstance().CaptureConcurrentCheck(streamIndex);
922 AUDIO_INFO_LOG("ret:%{public}d streamIndex_:%{public}d status_:%{public}u", ret, streamIndex, status_.load());
923 }
924 } // namespace AudioStandard
925 } // namespace OHOS
926