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