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 &timestamp)
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