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