• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &timestamp)
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