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
36 namespace OHOS {
37 namespace AudioStandard {
38 namespace {
39 static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
40 static const size_t CAPTURER_BUFFER_DEFAULT_NUM = 4;
41 static const size_t CAPTURER_BUFFER_WAKE_UP_NUM = 100;
42 static const uint32_t OVERFLOW_LOG_LOOP_COUNT = 100;
43 }
44
CapturerInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)45 CapturerInServer::CapturerInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
46 {
47 processConfig_ = processConfig;
48 streamListener_ = streamListener;
49 innerCapId_ = processConfig.innerCapId;
50 }
51
~CapturerInServer()52 CapturerInServer::~CapturerInServer()
53 {
54 if (status_ != I_STATUS_RELEASED) {
55 Release();
56 }
57 DumpFileUtil::CloseDumpFile(&dumpS2C_);
58 if (needCheckBackground_) {
59 TurnOffMicIndicator(CAPTURER_INVALID);
60 }
61 }
62
ConfigServerBuffer()63 int32_t CapturerInServer::ConfigServerBuffer()
64 {
65 if (audioServerBuffer_ != nullptr) {
66 AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
67 return SUCCESS;
68 }
69
70 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "ConfigServerBuffer failed, stream_ is null");
71 stream_->GetSpanSizePerFrame(spanSizeInFrame_);
72 const size_t bufferNum = ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_WAKEUP)
73 ? CAPTURER_BUFFER_WAKE_UP_NUM : CAPTURER_BUFFER_DEFAULT_NUM);
74 totalSizeInFrame_ = spanSizeInFrame_ * bufferNum;
75 stream_->GetByteSizePerFrame(byteSizePerFrame_);
76 spanSizeInBytes_ = byteSizePerFrame_ * spanSizeInFrame_;
77 AUDIO_INFO_LOG("ConfigProcessBuffer: totalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu,"
78 "byteSizePerFrame_: %{public}zu, spanSizeInBytes_ %{public}zu", totalSizeInFrame_, spanSizeInFrame_,
79 byteSizePerFrame_, spanSizeInBytes_);
80 if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) {
81 AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
82 return ERR_INVALID_PARAM;
83 }
84
85 int32_t ret = InitCacheBuffer(2 * spanSizeInBytes_);
86 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitCacheBuffer failed %{public}d", ret);
87
88 // create OHAudioBuffer in server
89 audioServerBuffer_ = OHAudioBuffer::CreateFromLocal(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_);
90 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
91
92 // we need to clear data buffer to avoid dirty data.
93 memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
94 audioServerBuffer_->GetDataSize());
95 ret = InitBufferStatus();
96 AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
97 isBufferConfiged_ = true;
98 isInited_ = true;
99 return SUCCESS;
100 }
101
InitBufferStatus()102 int32_t CapturerInServer::InitBufferStatus()
103 {
104 if (audioServerBuffer_ == nullptr) {
105 AUDIO_ERR_LOG("InitBufferStatus failed, null buffer.");
106 return ERR_ILLEGAL_STATE;
107 }
108
109 uint32_t spanCount = audioServerBuffer_->GetSpanCount();
110 AUDIO_INFO_LOG("InitBufferStatus: spanCount %{public}u", spanCount);
111 for (uint32_t i = 0; i < spanCount; i++) {
112 SpanInfo *spanInfo = audioServerBuffer_->GetSpanInfoByIndex(i);
113 if (spanInfo == nullptr) {
114 AUDIO_ERR_LOG("InitBufferStatus failed, null spaninfo");
115 return ERR_ILLEGAL_STATE;
116 }
117 spanInfo->spanStatus = SPAN_READ_DONE;
118 spanInfo->offsetInFrame = 0;
119
120 spanInfo->readStartTime = 0;
121 spanInfo->readDoneTime = 0;
122
123 spanInfo->readStartTime = 0;
124 spanInfo->readDoneTime = 0;
125
126 spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
127 spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
128 spanInfo->isMute = false;
129 }
130 return SUCCESS;
131 }
132
Init()133 int32_t CapturerInServer::Init()
134 {
135 int32_t ret = IStreamManager::GetRecorderManager().CreateCapturer(processConfig_, stream_);
136 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
137 "Construct CapturerInServer failed: %{public}d", ret);
138 streamIndex_ = stream_->GetStreamIndex();
139 ret = ConfigServerBuffer();
140 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "ConfigServerBuffer failed: %{public}d", ret);
141 stream_->RegisterStatusCallback(shared_from_this());
142 stream_->RegisterReadCallback(shared_from_this());
143
144 traceTag_ = "[" + std::to_string(streamIndex_) + "]CapturerInServer"; // [100001]CapturerInServer
145 // eg: /data/data/.pulse_dir/10000_100009_capturer_server_out_48000_2_1.pcm
146 AudioStreamInfo tempInfo = processConfig_.streamInfo;
147 dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
148 + "_capturer_server_out_" + std::to_string(tempInfo.samplingRate) + "_"
149 + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
150 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpS2C_);
151 recorderDfx_ = std::make_unique<RecorderDfxWriter>(processConfig_.appInfo, streamIndex_);
152
153 return SUCCESS;
154 }
155
OnStatusUpdate(IOperation operation)156 void CapturerInServer::OnStatusUpdate(IOperation operation)
157 {
158 AUDIO_INFO_LOG("CapturerInServer::OnStatusUpdate operation: %{public}d", operation);
159 operation_ = operation;
160 if (status_ == I_STATUS_RELEASED) {
161 AUDIO_WARNING_LOG("Stream already released");
162 return;
163 }
164 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
165 CHECK_AND_RETURN_LOG((stateListener != nullptr && recorderDfx_ != nullptr), "IStreamListener is nullptr");
166 switch (operation) {
167 case OPERATION_UNDERFLOW:
168 underflowCount += 1;
169 AUDIO_INFO_LOG("Underflow!! underflow count %{public}d", underflowCount);
170 stateListener->OnOperationHandled(BUFFER_OVERFLOW, underflowCount);
171 break;
172 case OPERATION_STARTED:
173 status_ = I_STATUS_STARTED;
174 lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
175 std::chrono::system_clock::now().time_since_epoch()).count();
176 stateListener->OnOperationHandled(START_STREAM, 0);
177 break;
178 case OPERATION_PAUSED:
179 status_ = I_STATUS_PAUSED;
180 stateListener->OnOperationHandled(PAUSE_STREAM, 0);
181 recorderDfx_->WriteDfxActionMsg(streamIndex_, CAPTURER_STAGE_PAUSE_OK);
182 break;
183 case OPERATION_STOPPED:
184 status_ = I_STATUS_STOPPED;
185 stateListener->OnOperationHandled(STOP_STREAM, 0);
186 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
187 std::chrono::system_clock::now().time_since_epoch()).count();
188 recorderDfx_->WriteDfxStopMsg(streamIndex_, CAPTURER_STAGE_STOP_OK,
189 GetLastAudioDuration(), processConfig_);
190 break;
191 case OPERATION_FLUSHED:
192 HandleOperationFlushed();
193 stateListener->OnOperationHandled(FLUSH_STREAM, 0);
194 break;
195 default:
196 AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
197 status_ = I_STATUS_INVALID;
198 }
199 }
200
HandleOperationFlushed()201 void CapturerInServer::HandleOperationFlushed()
202 {
203 if (status_ == I_STATUS_FLUSHING_WHEN_STARTED) {
204 status_ = I_STATUS_STARTED;
205 } else if (status_ == I_STATUS_FLUSHING_WHEN_PAUSED) {
206 status_ = I_STATUS_PAUSED;
207 } else if (status_ == I_STATUS_FLUSHING_WHEN_STOPPED) {
208 status_ = I_STATUS_STOPPED;
209 } else {
210 AUDIO_WARNING_LOG("Invalid status before flusing");
211 }
212 }
213
DequeueBuffer(size_t length)214 BufferDesc CapturerInServer::DequeueBuffer(size_t length)
215 {
216 return stream_->DequeueBuffer(length);
217 }
218
IsReadDataOverFlow(size_t length,uint64_t currentWriteFrame,std::shared_ptr<IStreamListener> stateListener)219 bool CapturerInServer::IsReadDataOverFlow(size_t length, uint64_t currentWriteFrame,
220 std::shared_ptr<IStreamListener> stateListener)
221 {
222 if (audioServerBuffer_->GetAvailableDataFrames() <= static_cast<int32_t>(spanSizeInFrame_)) {
223 if (overFlowLogFlag_ == 0) {
224 AUDIO_INFO_LOG("OverFlow!!!");
225 } else if (overFlowLogFlag_ == OVERFLOW_LOG_LOOP_COUNT) {
226 overFlowLogFlag_ = 0;
227 }
228 overFlowLogFlag_++;
229 BufferDesc dstBuffer = stream_->DequeueBuffer(length);
230 stream_->EnqueueBuffer(dstBuffer);
231 stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame);
232 return true;
233 }
234 return false;
235 }
236
ReadData(size_t length)237 void CapturerInServer::ReadData(size_t length)
238 {
239 CHECK_AND_RETURN_LOG(length >= spanSizeInBytes_,
240 "Length %{public}zu is less than spanSizeInBytes %{public}zu", length, spanSizeInBytes_);
241 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
242 CHECK_AND_RETURN_LOG(stateListener != nullptr, "IStreamListener is nullptr");
243 CHECK_AND_RETURN_LOG(stream_ != nullptr, "ReadData failed, stream_ is null");
244
245 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
246 if (IsReadDataOverFlow(length, currentWriteFrame, stateListener)) {
247 return;
248 }
249 Trace trace(traceTag_ + "::ReadData:" + std::to_string(currentWriteFrame));
250 OptResult result = ringCache_->GetWritableSize();
251 CHECK_AND_RETURN_LOG(result.ret == OPERATION_SUCCESS, "RingCache write invalid size %{public}zu", result.size);
252 BufferDesc srcBuffer = stream_->DequeueBuffer(result.size);
253 ringCache_->Enqueue({srcBuffer.buffer, srcBuffer.bufLength});
254 result = ringCache_->GetReadableSize();
255 if (result.ret != OPERATION_SUCCESS || result.size < spanSizeInBytes_) {
256 stream_->EnqueueBuffer(srcBuffer);
257 return;
258 }
259
260 BufferDesc dstBuffer = {nullptr, 0, 0};
261 uint64_t curWritePos = audioServerBuffer_->GetCurWriteFrame();
262 if (audioServerBuffer_->GetWriteBuffer(curWritePos, dstBuffer) < 0) {
263 return;
264 }
265 if ((processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode ==
266 LEGACY_MUTE_CAP) || muteFlag_) {
267 dstBuffer.buffer = dischargeBuffer_.get(); // discharge valid data.
268 }
269 if (muteFlag_) {
270 memset_s(static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength, 0, dstBuffer.bufLength);
271 }
272 ringCache_->Dequeue({dstBuffer.buffer, dstBuffer.bufLength});
273 VolumeTools::DfxOperation(dstBuffer, processConfig_.streamInfo, traceTag_, volumeDataCount_);
274 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
275 DumpFileUtil::WriteDumpFile(dumpS2C_, static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
276 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
277 static_cast<void *>(dstBuffer.buffer), dstBuffer.bufLength);
278 }
279
280 uint64_t nextWriteFrame = currentWriteFrame + spanSizeInFrame_;
281 audioServerBuffer_->SetCurWriteFrame(nextWriteFrame);
282 audioServerBuffer_->SetHandleInfo(currentWriteFrame, ClockTime::GetCurNano());
283
284 stream_->EnqueueBuffer(srcBuffer);
285 stateListener->OnOperationHandled(UPDATE_STREAM, currentWriteFrame);
286 }
287
OnReadData(size_t length)288 int32_t CapturerInServer::OnReadData(size_t length)
289 {
290 Trace trace(traceTag_ + "::OnReadData:" + std::to_string(length));
291 ReadData(length);
292 return SUCCESS;
293 }
294
UpdateReadIndex()295 int32_t CapturerInServer::UpdateReadIndex()
296 {
297 AUDIO_DEBUG_LOG("audioServerBuffer_->GetAvailableDataFrames(): %{public}d, needStart: %{public}d",
298 audioServerBuffer_->GetAvailableDataFrames(), needStart);
299 return SUCCESS;
300 }
301
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)302 int32_t CapturerInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
303 {
304 buffer = audioServerBuffer_;
305 return SUCCESS;
306 }
307
GetSessionId(uint32_t & sessionId)308 int32_t CapturerInServer::GetSessionId(uint32_t &sessionId)
309 {
310 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
311 sessionId = streamIndex_;
312 CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
313 sessionId);
314
315 return SUCCESS;
316 }
317
TurnOnMicIndicator(CapturerState capturerState)318 bool CapturerInServer::TurnOnMicIndicator(CapturerState capturerState)
319 {
320 uint32_t tokenId = processConfig_.appInfo.appTokenId;
321 uint64_t fullTokenId = processConfig_.appInfo.appFullTokenId;
322 SwitchStreamInfo info = {
323 streamIndex_,
324 processConfig_.callerUid,
325 processConfig_.appInfo.appUid,
326 processConfig_.appInfo.appPid,
327 tokenId,
328 capturerState,
329 };
330 if (!SwitchStreamUtil::IsSwitchStreamSwitching(info, SWITCH_STATE_STARTED)) {
331 CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId),
332 false, "VerifyBackgroundCapture failed!");
333 }
334 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_STARTED);
335
336 if (isMicIndicatorOn_) {
337 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already on."
338 "No need to call NotifyPrivacyStart!", streamIndex_);
339 } else {
340 CHECK_AND_RETURN_RET_LOG(PermissionUtil::NotifyPrivacyStart(tokenId, streamIndex_),
341 false, "NotifyPrivacyStart failed!");
342 AUDIO_INFO_LOG("Turn on micIndicator of stream:%{public}d from off"
343 "after NotifyPrivacyStart success!", streamIndex_);
344 isMicIndicatorOn_ = true;
345 }
346 return true;
347 }
348
TurnOffMicIndicator(CapturerState capturerState)349 bool CapturerInServer::TurnOffMicIndicator(CapturerState capturerState)
350 {
351 uint32_t tokenId = processConfig_.appInfo.appTokenId;
352 SwitchStreamInfo info = {
353 streamIndex_,
354 processConfig_.callerUid,
355 processConfig_.appInfo.appUid,
356 processConfig_.appInfo.appPid,
357 tokenId,
358 capturerState,
359 };
360 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_FINISHED);
361
362 if (isMicIndicatorOn_) {
363 PermissionUtil::NotifyPrivacyStop(tokenId, streamIndex_);
364 AUDIO_INFO_LOG("Turn off micIndicator of stream:%{public}d from on after NotifyPrivacyStop!", streamIndex_);
365 isMicIndicatorOn_ = false;
366 } else {
367 AUDIO_WARNING_LOG("MicIndicator of stream:%{public}d is already off."
368 "No need to call NotifyPrivacyStop!", streamIndex_);
369 }
370 return true;
371 }
372
Start()373 int32_t CapturerInServer::Start()
374 {
375 int32_t ret = StartInner();
376 CapturerStage stage = ret == SUCCESS ? CAPTURER_STAGE_START_OK : CAPTURER_STAGE_START_FAIL;
377 if (recorderDfx_) {
378 recorderDfx_->WriteDfxStartMsg(streamIndex_, stage, processConfig_);
379 }
380 return ret;
381 }
382
StartInner()383 int32_t CapturerInServer::StartInner()
384 {
385 needStart = 0;
386 std::unique_lock<std::mutex> lock(statusLock_);
387
388 if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
389 AUDIO_ERR_LOG("CapturerInServer::Start failed, Illegal state: %{public}u", status_);
390 return ERR_ILLEGAL_STATE;
391 }
392
393 if (!needCheckBackground_ && PermissionUtil::NeedVerifyBackgroundCapture(processConfig_.callerUid,
394 processConfig_.capturerInfo.sourceType)) {
395 AUDIO_INFO_LOG("set needCheckBackground_: true");
396 needCheckBackground_ = true;
397 }
398 if (needCheckBackground_) {
399 CHECK_AND_RETURN_RET_LOG(TurnOnMicIndicator(CAPTURER_RUNNING), ERR_PERMISSION_DENIED,
400 "Turn on micIndicator failed or check backgroud capture failed for stream:%{public}d!", streamIndex_);
401 }
402
403 AudioService::GetInstance()->UpdateSourceType(processConfig_.capturerInfo.sourceType);
404
405 status_ = I_STATUS_STARTING;
406 int ret = stream_->Start();
407 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
408 resetTime_ = true;
409 return SUCCESS;
410 }
411
Pause()412 int32_t CapturerInServer::Pause()
413 {
414 std::unique_lock<std::mutex> lock(statusLock_);
415 if (status_ != I_STATUS_STARTED) {
416 AUDIO_ERR_LOG("CapturerInServer::Pause failed, Illegal state: %{public}u", status_);
417 return ERR_ILLEGAL_STATE;
418 }
419 if (needCheckBackground_) {
420 TurnOffMicIndicator(CAPTURER_PAUSED);
421 }
422 status_ = I_STATUS_PAUSING;
423 int ret = stream_->Pause();
424 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
425 return SUCCESS;
426 }
427
Flush()428 int32_t CapturerInServer::Flush()
429 {
430 std::unique_lock<std::mutex> lock(statusLock_);
431 if (status_ == I_STATUS_STARTED) {
432 status_ = I_STATUS_FLUSHING_WHEN_STARTED;
433 } else if (status_ == I_STATUS_PAUSED) {
434 status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
435 } else if (status_ == I_STATUS_STOPPED) {
436 status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
437 } else {
438 AUDIO_ERR_LOG("CapturerInServer::Flush failed, Illegal state: %{public}u", status_);
439 return ERR_ILLEGAL_STATE;
440 }
441
442 // Flush buffer of audio server
443 uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
444 uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
445
446 while (readFrame < writeFrame) {
447 BufferDesc bufferDesc = {nullptr, 0, 0};
448 int32_t readResult = audioServerBuffer_->GetReadbuffer(readFrame, bufferDesc);
449 if (readResult != 0) {
450 return ERR_OPERATION_FAILED;
451 }
452 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
453 readFrame += spanSizeInFrame_;
454 AUDIO_INFO_LOG("On flush, write frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
455 "readFrame: %{public}" PRIu64 "", writeFrame, spanSizeInFrame_, readFrame);
456 audioServerBuffer_->SetCurReadFrame(readFrame);
457 }
458
459 int ret = stream_->Flush();
460 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
461 return SUCCESS;
462 }
463
DrainAudioBuffer()464 int32_t CapturerInServer::DrainAudioBuffer()
465 {
466 return SUCCESS;
467 }
468
Stop()469 int32_t CapturerInServer::Stop()
470 {
471 std::unique_lock<std::mutex> lock(statusLock_);
472 if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED) {
473 AUDIO_ERR_LOG("CapturerInServer::Stop failed, Illegal state: %{public}u", status_);
474 return ERR_ILLEGAL_STATE;
475 }
476 status_ = I_STATUS_STOPPING;
477
478 if (needCheckBackground_) {
479 TurnOffMicIndicator(CAPTURER_STOPPED);
480 }
481
482 int ret = stream_->Stop();
483 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
484 return SUCCESS;
485 }
486
Release()487 int32_t CapturerInServer::Release()
488 {
489 AudioService::GetInstance()->RemoveCapturer(streamIndex_);
490 {
491 std::unique_lock<std::mutex> lock(statusLock_);
492 if (status_ == I_STATUS_RELEASED) {
493 AUDIO_INFO_LOG("Already released");
494 return SUCCESS;
495 }
496 }
497 AUDIO_INFO_LOG("Start release capturer");
498 int32_t ret = IStreamManager::GetRecorderManager().ReleaseCapturer(streamIndex_);
499 if (ret < 0) {
500 AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
501 status_ = I_STATUS_INVALID;
502 return ret;
503 }
504 status_ = I_STATUS_RELEASED;
505 #ifdef HAS_FEATURE_INNERCAPTURER
506 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
507 AUDIO_INFO_LOG("Disable inner capturer for %{public}u, innerCapId :%{public}d, innerCapMode:%{public}d",
508 streamIndex_, innerCapId_, processConfig_.innerCapMode);
509 if (processConfig_.innerCapMode == MODERN_INNER_CAP) {
510 PlaybackCapturerManager::GetInstance()->RemovePlaybackCapturerFilterInfo(streamIndex_, innerCapId_);
511 } else {
512 PlaybackCapturerManager::GetInstance()->SetInnerCapturerState(false);
513 }
514 if (PlaybackCapturerManager::GetInstance()->CheckReleaseUnloadModernInnerCapSink(innerCapId_)) {
515 AudioService::GetInstance()->UnloadModernInnerCapSink(innerCapId_);
516 }
517 innerCapId_ = 0;
518 }
519 #endif
520 if (needCheckBackground_) {
521 TurnOffMicIndicator(CAPTURER_RELEASED);
522 }
523 return SUCCESS;
524 }
525
526 #ifdef HAS_FEATURE_INNERCAPTURER
UpdatePlaybackCaptureConfigInLegacy(const AudioPlaybackCaptureConfig & config)527 int32_t CapturerInServer::UpdatePlaybackCaptureConfigInLegacy(const AudioPlaybackCaptureConfig &config)
528 {
529 Trace trace("UpdatePlaybackCaptureConfigInLegacy");
530 // Legacy mode, only usage filter works.
531 AUDIO_INFO_LOG("Update config in legacy mode with %{public}zu usage", config.filterOptions.usages.size());
532
533 std::vector<int32_t> usage;
534 for (size_t i = 0; i < config.filterOptions.usages.size(); i++) {
535 usage.push_back(config.filterOptions.usages[i]);
536 }
537
538 PlaybackCapturerManager::GetInstance()->SetSupportStreamUsage(usage);
539 PlaybackCapturerManager::GetInstance()->SetInnerCapturerState(true);
540 return SUCCESS;
541 }
542
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)543 int32_t CapturerInServer::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
544 {
545 Trace trace("UpdatePlaybackCaptureConfig:" + ProcessConfig::DumpInnerCapConfig(config));
546 CHECK_AND_RETURN_RET_LOG(processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE,
547 ERR_INVALID_OPERATION, "This not a inner-cap source!");
548
549 AUDIO_INFO_LOG("Client using config: %{public}s", ProcessConfig::DumpInnerCapConfig(config).c_str());
550
551 for (auto &usg : config.filterOptions.usages) {
552 if (usg != STREAM_USAGE_VOICE_COMMUNICATION) {
553 continue;
554 }
555
556 if (!PermissionUtil::VerifyPermission(CAPTURER_VOICE_DOWNLINK_PERMISSION, processConfig_.appInfo.appTokenId)) {
557 AUDIO_ERR_LOG("downlink capturer permission check failed");
558 return ERR_PERMISSION_DENIED;
559 }
560 }
561 filterConfig_ = config;
562
563 if (filterConfig_.filterOptions.usages.size() == 0) {
564 std::vector<StreamUsage> defalutUsages = PlaybackCapturerManager::GetInstance()->GetDefaultUsages();
565 for (size_t i = 0; i < defalutUsages.size(); i++) {
566 filterConfig_.filterOptions.usages.push_back(defalutUsages[i]);
567 }
568 AUDIO_INFO_LOG("Reset config to %{public}s", ProcessConfig::DumpInnerCapConfig(filterConfig_).c_str());
569 }
570
571 if (processConfig_.innerCapMode != MODERN_INNER_CAP) {
572 return UpdatePlaybackCaptureConfigInLegacy(filterConfig_);
573 }
574
575 // in plan: add more check and print config
576 PlaybackCapturerManager::GetInstance()->SetPlaybackCapturerFilterInfo(streamIndex_, filterConfig_, innerCapId_);
577 return SUCCESS;
578 }
579 #endif
580
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)581 int32_t CapturerInServer::GetAudioTime(uint64_t &framePos, uint64_t ×tamp)
582 {
583 if (status_ == I_STATUS_STOPPED) {
584 AUDIO_WARNING_LOG("Current status is stopped");
585 return ERR_ILLEGAL_STATE;
586 }
587
588 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetAudioTime failed, stream_ is null");
589 stream_->GetStreamFramesRead(framePos);
590 stream_->GetCurrentTimeStamp(timestamp);
591 if (resetTime_) {
592 resetTime_ = false;
593 resetTimestamp_ = timestamp;
594 }
595 return SUCCESS;
596 }
597
GetLatency(uint64_t & latency)598 int32_t CapturerInServer::GetLatency(uint64_t &latency)
599 {
600 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetLatency failed, stream_ is null");
601 return stream_->GetLatency(latency);
602 }
603
InitCacheBuffer(size_t targetSize)604 int32_t CapturerInServer::InitCacheBuffer(size_t targetSize)
605 {
606 CHECK_AND_RETURN_RET_LOG(spanSizeInBytes_ != 0, ERR_OPERATION_FAILED, "spanSizeInByte_ invalid");
607
608 AUDIO_INFO_LOG("old size:%{public}zu, new size:%{public}zu", cacheSizeInBytes_, targetSize);
609 cacheSizeInBytes_ = targetSize;
610
611 if (ringCache_ == nullptr) {
612 ringCache_ = AudioRingCache::Create(cacheSizeInBytes_);
613 } else {
614 OptResult result = ringCache_->ReConfig(cacheSizeInBytes_, false); // false --> clear buffer
615 if (result.ret != OPERATION_SUCCESS) {
616 AUDIO_ERR_LOG("ReConfig AudioRingCache to size %{public}u failed:ret%{public}zu", result.ret, targetSize);
617 return ERR_OPERATION_FAILED;
618 }
619 }
620
621 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && processConfig_.innerCapMode ==
622 LEGACY_MUTE_CAP) {
623 dischargeBuffer_ = std::make_unique<uint8_t []>(cacheSizeInBytes_);
624 }
625
626 return SUCCESS;
627 }
628
SetNonInterruptMute(const bool muteFlag)629 void CapturerInServer::SetNonInterruptMute(const bool muteFlag)
630 {
631 AUDIO_INFO_LOG("muteFlag: %{public}d", muteFlag);
632 muteFlag_ = muteFlag;
633 AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
634 }
635
RestoreSession(RestoreInfo restoreInfo)636 RestoreStatus CapturerInServer::RestoreSession(RestoreInfo restoreInfo)
637 {
638 RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
639 if (restoreStatus == NEED_RESTORE) {
640 audioServerBuffer_->SetRestoreInfo(restoreInfo);
641 }
642 return restoreStatus;
643 }
644
GetLastAudioDuration()645 int64_t CapturerInServer::GetLastAudioDuration()
646 {
647 auto ret = lastStopTime_ - lastStartTime_;
648 return ret < 0 ? -1 : ret;
649 }
650
651 } // namespace AudioStandard
652 } // namespace OHOS
653