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