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 FAST_AUDIO_STREAM_H
16 #define FAST_AUDIO_STREAM_H
17
18 #ifndef LOG_TAG
19 #define LOG_TAG "CapturerInClientInner"
20 #endif
21
22 #include "capturer_in_client.h"
23 #include "capturer_in_client_inner.h"
24
25 #include <atomic>
26 #include <cinttypes>
27 #include <condition_variable>
28 #include <sstream>
29 #include <string>
30 #include <mutex>
31 #include <thread>
32
33 #include "iservice_registry.h"
34 #include "system_ability_definition.h"
35 #include "securec.h"
36
37 #include "iipc_stream.h"
38 #include "audio_capturer_log.h"
39 #include "audio_errors.h"
40 #include "volume_tools.h"
41 #include "audio_manager_base.h"
42 #include "audio_ring_cache.h"
43 #include "audio_utils.h"
44 #include "audio_policy_manager.h"
45 #include "audio_server_death_recipient.h"
46 #include "audio_stream_tracker.h"
47 #include "audio_system_manager.h"
48 #include "audio_process_config.h"
49 #include "ipc_stream_listener_impl.h"
50 #include "ipc_stream_listener_stub.h"
51 #include "callback_handler.h"
52 #include "audio_safe_block_queue.h"
53 #include "istandard_audio_service.h"
54
55 namespace OHOS {
56 namespace AudioStandard {
57 namespace {
58 static const size_t MAX_CLIENT_READ_SIZE = 20 * 1024 * 1024; // 20M
59 static const int32_t CREATE_TIMEOUT_IN_SECOND = 9; // 9S
60 static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms
61 static const int32_t LOGLITMITTIMES = 20;
62 const uint64_t DEFAULT_BUF_DURATION_IN_USEC = 20000; // 20ms
63 const uint64_t MAX_BUF_DURATION_IN_USEC = 2000000; // 2S
64 const int64_t INVALID_FRAME_SIZE = -1;
65 static const int32_t SHORT_TIMEOUT_IN_MS = 20; // ms
66 static constexpr int CB_QUEUE_CAPACITY = 3;
67 constexpr int32_t RETRY_WAIT_TIME_MS = 500; // 500ms
68 constexpr int32_t MAX_RETRY_COUNT = 8;
69 const float ERROR_VOLUME = -0.1f;
70 }
71
GetInstance(AudioStreamType eStreamType,int32_t appUid)72 std::shared_ptr<CapturerInClient> CapturerInClient::GetInstance(AudioStreamType eStreamType, int32_t appUid)
73 {
74 return std::make_shared<CapturerInClientInner>(eStreamType, appUid);
75 }
76
CapturerInClientInner(AudioStreamType eStreamType,int32_t appUid)77 CapturerInClientInner::CapturerInClientInner(AudioStreamType eStreamType, int32_t appUid) : eStreamType_(eStreamType),
78 appUid_(appUid), cbBufferQueue_(CB_QUEUE_CAPACITY)
79 {
80 AUDIO_INFO_LOG("Create with StreamType:%{public}d appUid:%{public}d ", eStreamType_, appUid_);
81 audioStreamTracker_ = std::make_unique<AudioStreamTracker>(AUDIO_MODE_RECORD, appUid);
82 state_ = NEW;
83 }
84
~CapturerInClientInner()85 CapturerInClientInner::~CapturerInClientInner()
86 {
87 AUDIO_INFO_LOG("~CapturerInClientInner()");
88 CapturerInClientInner::ReleaseAudioStream(true);
89 AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
90 }
91
OnOperationHandled(Operation operation,int64_t result)92 int32_t CapturerInClientInner::OnOperationHandled(Operation operation, int64_t result)
93 {
94 // read/write operation may print many log, use debug.
95 if (operation == UPDATE_STREAM) {
96 AUDIO_DEBUG_LOG("OnOperationHandled() UPDATE_STREAM result:%{public}" PRId64".", result);
97 // notify write if blocked
98 readDataCV_.notify_all();
99 return SUCCESS;
100 }
101
102 if (operation == BUFFER_OVERFLOW) {
103 AUDIO_WARNING_LOG("recv overflow %{public}d", overflowCount_);
104 // in plan next: do more to reduce overflow
105 readDataCV_.notify_all();
106 return SUCCESS;
107 }
108
109 if (operation == RESTORE_SESSION) {
110 if (audioStreamTracker_ && audioStreamTracker_.get()) {
111 audioStreamTracker_->FetchInputDeviceForTrack(sessionId_, state_, clientPid_, capturerInfo_);
112 }
113 return SUCCESS;
114 }
115
116 AUDIO_INFO_LOG("OnOperationHandled() recv operation:%{public}d result:%{public}" PRId64".", operation, result);
117 std::unique_lock<std::mutex> lock(callServerMutex_);
118 notifiedOperation_ = operation;
119 notifiedResult_ = result;
120
121 callServerCV_.notify_all();
122 return SUCCESS;
123 }
124
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId,uint64_t fullTokenId)125 void CapturerInClientInner::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId, uint64_t fullTokenId)
126 {
127 AUDIO_INFO_LOG("PID:%{public}d UID:%{public}d.", clientPid, clientUid);
128 clientPid_ = clientPid;
129 clientUid_ = clientUid;
130 appTokenId_ = appTokenId;
131 fullTokenId_ = fullTokenId;
132 return;
133 }
134
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)135 int32_t CapturerInClientInner::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
136 {
137 #ifdef HAS_FEATURE_INNERCAPTURER
138 AUDIO_INFO_LOG("client set %{public}s", ProcessConfig::DumpInnerCapConfig(config).c_str());
139 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "IpcStream is already nullptr");
140 int32_t ret = ipcStream_->UpdatePlaybackCaptureConfig(config);
141 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "failed: %{public}d", ret);
142
143 filterConfig_ = config;
144 #endif
145 return SUCCESS;
146 }
147
SetRendererInfo(const AudioRendererInfo & rendererInfo)148 void CapturerInClientInner::SetRendererInfo(const AudioRendererInfo &rendererInfo)
149 {
150 AUDIO_WARNING_LOG("SetRendererInfo is not supported");
151 return;
152 }
153
GetRendererInfo(AudioRendererInfo & rendererInfo)154 void CapturerInClientInner::GetRendererInfo(AudioRendererInfo &rendererInfo)
155 {
156 AUDIO_WARNING_LOG("GetRendererInfo is not supported");
157 }
158
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)159 void CapturerInClientInner::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
160 {
161 capturerInfo_ = capturerInfo;
162 capturerInfo_.samplingRate = static_cast<AudioSamplingRate>(streamParams_.samplingRate);
163 capturerInfo_.encodingType = streamParams_.encoding;
164 capturerInfo_.channelLayout = streamParams_.channelLayout;
165 AUDIO_INFO_LOG("SetCapturerInfo with SourceType %{public}d flag %{public}d", capturerInfo_.sourceType,
166 capturerInfo_.capturerFlags);
167 return;
168 }
169
RegisterTracker(const std::shared_ptr<AudioClientTracker> & proxyObj)170 void CapturerInClientInner::RegisterTracker(const std::shared_ptr<AudioClientTracker> &proxyObj)
171 {
172 if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) {
173 // make sure sessionId_ is set before.
174 AUDIO_INFO_LOG("Calling register tracker, sessionid = %{public}d", sessionId_);
175 AudioRegisterTrackerInfo registerTrackerInfo;
176
177 capturerInfo_.samplingRate = static_cast<AudioSamplingRate>(streamParams_.samplingRate);
178 registerTrackerInfo.sessionId = sessionId_;
179 registerTrackerInfo.clientPid = clientPid_;
180 registerTrackerInfo.state = state_;
181 registerTrackerInfo.rendererInfo = rendererInfo_;
182 registerTrackerInfo.capturerInfo = capturerInfo_;
183 registerTrackerInfo.appTokenId = appTokenId_;
184
185 audioStreamTracker_->RegisterTracker(registerTrackerInfo, proxyObj);
186 streamTrackerRegistered_ = true;
187 }
188 }
189
UpdateTracker(const std::string & updateCase)190 void CapturerInClientInner::UpdateTracker(const std::string &updateCase)
191 {
192 if (audioStreamTracker_ && audioStreamTracker_.get()) {
193 AUDIO_DEBUG_LOG("Capturer:Calling Update tracker for %{public}s", updateCase.c_str());
194 audioStreamTracker_->UpdateTracker(sessionId_, state_, clientPid_, rendererInfo_, capturerInfo_);
195 }
196 }
197
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj,const AudioPlaybackCaptureConfig & config)198 int32_t CapturerInClientInner::SetAudioStreamInfo(const AudioStreamParams info,
199 const std::shared_ptr<AudioClientTracker> &proxyObj,
200 const AudioPlaybackCaptureConfig &config)
201 {
202 AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d, stream type:"
203 " %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_,
204 info.encoding);
205 AudioXCollie guard("CapturerInClientInner::SetAudioStreamInfo", CREATE_TIMEOUT_IN_SECOND,
206 nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG);
207 if (!IsFormatValid(info.format) || !IsEncodingTypeValid(info.encoding) || !IsSamplingRateValid(info.samplingRate)) {
208 AUDIO_ERR_LOG("CapturerInClient: Unsupported audio parameter");
209 return ERR_NOT_SUPPORTED;
210 }
211 if (!IsRecordChannelRelatedInfoValid(info.channels, info.channelLayout)) {
212 AUDIO_ERR_LOG("Invalid sink channel %{public}d or channel layout %{public}" PRIu64, info.channels,
213 info.channelLayout);
214 return ERR_NOT_SUPPORTED;
215 }
216
217 CHECK_AND_RETURN_RET_LOG(IAudioStream::GetByteSizePerFrame(info, sizePerFrameInByte_) == SUCCESS,
218 ERROR_INVALID_PARAM, "GetByteSizePerFrame failed with invalid params");
219
220 if (state_ != NEW) {
221 AUDIO_INFO_LOG("State is %{public}d, not new, release existing stream and recreate.", state_.load());
222 int32_t ret = DeinitIpcStream();
223 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "release existing stream failed.");
224 }
225
226 streamParams_ = info; // keep it for later use
227 paramsIsSet_ = true;
228 int32_t initRet = InitIpcStream(config);
229 CHECK_AND_RETURN_RET_LOG(initRet == SUCCESS, initRet, "Init stream failed: %{public}d", initRet);
230 state_ = PREPARED;
231 logUtilsTag_ = "[" + std::to_string(sessionId_) + "]NormalCapturer";
232
233 proxyObj_ = proxyObj;
234 RegisterTracker(proxyObj);
235 return SUCCESS;
236 }
237
238 std::mutex g_serverMutex;
239 sptr<IStandardAudioService> g_ServerProxy = nullptr;
GetAudioServerProxy()240 const sptr<IStandardAudioService> CapturerInClientInner::GetAudioServerProxy()
241 {
242 std::lock_guard<std::mutex> lock(g_serverMutex);
243 if (g_ServerProxy == nullptr) {
244 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
245 if (samgr == nullptr) {
246 AUDIO_ERR_LOG("GetAudioServerProxy: get sa manager failed");
247 return nullptr;
248 }
249 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
250 if (object == nullptr) {
251 AUDIO_ERR_LOG("GetAudioServerProxy: get audio service remote object failed");
252 return nullptr;
253 }
254 g_ServerProxy = iface_cast<IStandardAudioService>(object);
255 if (g_ServerProxy == nullptr) {
256 AUDIO_ERR_LOG("GetAudioServerProxy: get audio service proxy failed");
257 return nullptr;
258 }
259
260 // register death recipent to restore proxy
261 sptr<AudioServerDeathRecipient> asDeathRecipient =
262 new(std::nothrow) AudioServerDeathRecipient(getpid(), getuid());
263 if (asDeathRecipient != nullptr) {
264 asDeathRecipient->SetNotifyCb([] (pid_t pid, pid_t uid) { AudioServerDied(pid, uid); });
265 bool result = object->AddDeathRecipient(asDeathRecipient);
266 if (!result) {
267 AUDIO_ERR_LOG("GetAudioServerProxy: failed to add deathRecipient");
268 }
269 }
270 }
271 sptr<IStandardAudioService> gasp = g_ServerProxy;
272 return gasp;
273 }
274
AudioServerDied(pid_t pid,pid_t uid)275 void CapturerInClientInner::AudioServerDied(pid_t pid, pid_t uid)
276 {
277 AUDIO_INFO_LOG("audio server died clear proxy, will restore proxy in next call");
278 std::lock_guard<std::mutex> lock(g_serverMutex);
279 g_ServerProxy = nullptr;
280 }
281
OnHandle(uint32_t code,int64_t data)282 void CapturerInClientInner::OnHandle(uint32_t code, int64_t data)
283 {
284 AUDIO_DEBUG_LOG("On handle event, event code: %{public}d, data: %{public}" PRIu64 "", code, data);
285 switch (code) {
286 case STATE_CHANGE_EVENT:
287 HandleStateChangeEvent(data);
288 break;
289 case RENDERER_MARK_REACHED_EVENT:
290 HandleCapturerMarkReachedEvent(data);
291 break;
292 case RENDERER_PERIOD_REACHED_EVENT:
293 HandleCapturerPeriodReachedEvent(data);
294 break;
295 default:
296 break;
297 }
298 }
299
HandleStateChangeEvent(int64_t data)300 void CapturerInClientInner::HandleStateChangeEvent(int64_t data)
301 {
302 State state = INVALID;
303 StateChangeCmdType cmdType = CMD_FROM_CLIENT;
304 ParamsToStateCmdType(data, state, cmdType);
305 std::unique_lock<std::mutex> lock(streamCbMutex_);
306 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
307 if (streamCb != nullptr) {
308 state = state != STOPPING ? state : STOPPED; // client only need STOPPED
309 streamCb->OnStateChange(state, cmdType);
310 }
311 }
312
HandleCapturerMarkReachedEvent(int64_t capturerMarkPosition)313 void CapturerInClientInner::HandleCapturerMarkReachedEvent(int64_t capturerMarkPosition)
314 {
315 AUDIO_DEBUG_LOG("Start HandleCapturerMarkReachedEvent");
316 std::unique_lock<std::mutex> lock(markReachMutex_);
317 if (capturerPositionCallback_) {
318 capturerPositionCallback_->OnMarkReached(capturerMarkPosition);
319 }
320 }
321
HandleCapturerPeriodReachedEvent(int64_t capturerPeriodNumber)322 void CapturerInClientInner::HandleCapturerPeriodReachedEvent(int64_t capturerPeriodNumber)
323 {
324 AUDIO_DEBUG_LOG("Start HandleCapturerPeriodReachedEvent");
325 std::unique_lock<std::mutex> lock(periodReachMutex_);
326 if (capturerPeriodPositionCallback_) {
327 capturerPeriodPositionCallback_->OnPeriodReached(capturerPeriodNumber);
328 }
329 }
330
331 // OnCapturerMarkReach by eventHandler
SendCapturerMarkReachedEvent(int64_t capturerMarkPosition)332 void CapturerInClientInner::SendCapturerMarkReachedEvent(int64_t capturerMarkPosition)
333 {
334 SafeSendCallbackEvent(RENDERER_MARK_REACHED_EVENT, capturerMarkPosition);
335 }
336
337 // OnCapturerPeriodReach by eventHandler
SendCapturerPeriodReachedEvent(int64_t capturerPeriodSize)338 void CapturerInClientInner::SendCapturerPeriodReachedEvent(int64_t capturerPeriodSize)
339 {
340 SafeSendCallbackEvent(RENDERER_PERIOD_REACHED_EVENT, capturerPeriodSize);
341 }
342
ParamsToStateCmdType(int64_t params,State & state,StateChangeCmdType & cmdType)343 int32_t CapturerInClientInner::ParamsToStateCmdType(int64_t params, State &state, StateChangeCmdType &cmdType)
344 {
345 cmdType = CMD_FROM_CLIENT;
346 switch (params) {
347 case HANDLER_PARAM_NEW:
348 state = NEW;
349 break;
350 case HANDLER_PARAM_PREPARED:
351 state = PREPARED;
352 break;
353 case HANDLER_PARAM_RUNNING:
354 state = RUNNING;
355 break;
356 case HANDLER_PARAM_STOPPED:
357 state = STOPPED;
358 break;
359 case HANDLER_PARAM_RELEASED:
360 state = RELEASED;
361 break;
362 case HANDLER_PARAM_PAUSED:
363 state = PAUSED;
364 break;
365 case HANDLER_PARAM_STOPPING:
366 state = STOPPING;
367 break;
368 case HANDLER_PARAM_RUNNING_FROM_SYSTEM:
369 state = RUNNING;
370 cmdType = CMD_FROM_SYSTEM;
371 break;
372 case HANDLER_PARAM_PAUSED_FROM_SYSTEM:
373 state = PAUSED;
374 cmdType = CMD_FROM_SYSTEM;
375 break;
376 default:
377 state = INVALID;
378 break;
379 }
380 return SUCCESS;
381 }
382
StateCmdTypeToParams(int64_t & params,State state,StateChangeCmdType cmdType)383 int32_t CapturerInClientInner::StateCmdTypeToParams(int64_t ¶ms, State state, StateChangeCmdType cmdType)
384 {
385 if (cmdType == CMD_FROM_CLIENT) {
386 params = static_cast<int64_t>(state);
387 return SUCCESS;
388 }
389 switch (state) {
390 case RUNNING:
391 params = HANDLER_PARAM_RUNNING_FROM_SYSTEM;
392 break;
393 case PAUSED:
394 params = HANDLER_PARAM_PAUSED_FROM_SYSTEM;
395 break;
396 default:
397 params = HANDLER_PARAM_INVALID;
398 break;
399 }
400 return SUCCESS;
401 }
402
SafeSendCallbackEvent(uint32_t eventCode,int64_t data)403 void CapturerInClientInner::SafeSendCallbackEvent(uint32_t eventCode, int64_t data)
404 {
405 std::lock_guard<std::mutex> lock(runnerMutex_);
406 AUDIO_INFO_LOG("Send callback event, code: %{public}u, data: %{public}" PRId64 "", eventCode, data);
407 CHECK_AND_RETURN_LOG(callbackHandler_ != nullptr && runnerReleased_ == false, "Runner is Released");
408 callbackHandler_->SendCallbackEvent(eventCode, data);
409 }
410
InitCallbackHandler()411 void CapturerInClientInner::InitCallbackHandler()
412 {
413 if (callbackHandler_ == nullptr) {
414 callbackHandler_ = CallbackHandler::GetInstance(shared_from_this(), "OS_AudioStateCB");
415 }
416 }
417
418 // call this without lock, we should be able to call deinit in any case.
DeinitIpcStream()419 int32_t CapturerInClientInner::DeinitIpcStream()
420 {
421 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, SUCCESS, "IpcStream is already nullptr");
422 ipcStream_->Release(false);
423 // in plan:
424 ipcStream_ = nullptr;
425 ringCache_->ResetBuffer();
426 return SUCCESS;
427 }
428
ConstructConfig()429 const AudioProcessConfig CapturerInClientInner::ConstructConfig()
430 {
431 AudioProcessConfig config = {};
432 // in plan: get token id
433 config.appInfo.appPid = clientPid_;
434 config.appInfo.appUid = clientUid_;
435 config.appInfo.appTokenId = appTokenId_;
436 config.appInfo.appFullTokenId = fullTokenId_;
437
438 config.streamInfo.channels = static_cast<AudioChannel>(streamParams_.channels);
439 config.streamInfo.encoding = static_cast<AudioEncodingType>(streamParams_.encoding);
440 config.streamInfo.format = static_cast<AudioSampleFormat>(streamParams_.format);
441 config.streamInfo.samplingRate = static_cast<AudioSamplingRate>(streamParams_.samplingRate);
442 config.streamInfo.channelLayout = static_cast<AudioChannelLayout>(streamParams_.channelLayout);
443 config.originalSessionId = streamParams_.originalSessionId;
444
445 config.audioMode = AUDIO_MODE_RECORD;
446
447 if (capturerInfo_.capturerFlags != 0) {
448 AUDIO_WARNING_LOG("ConstructConfig find Capturer flag invalid:%{public}d", capturerInfo_.capturerFlags);
449 capturerInfo_.capturerFlags = 0;
450 }
451 config.capturerInfo = capturerInfo_;
452
453 config.rendererInfo = {};
454
455 config.streamType = eStreamType_;
456
457 config.isInnerCapturer = isInnerCapturer_;
458 config.isWakeupCapturer = isWakeupCapturer_;
459 config.innerCapId = innerCapId_;
460
461 clientConfig_ = config;
462 return config;
463 }
464
InitSharedBuffer()465 int32_t CapturerInClientInner::InitSharedBuffer()
466 {
467 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "InitSharedBuffer failed, null ipcStream_.");
468 int32_t ret = ipcStream_->ResolveBuffer(clientBuffer_);
469 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && clientBuffer_ != nullptr, ret, "ResolveBuffer failed:%{public}d", ret);
470
471 uint32_t totalSizeInFrame = 0;
472 uint32_t byteSizePerFrame = 0;
473 ret = clientBuffer_->GetSizeParameter(totalSizeInFrame, spanSizeInFrame_, byteSizePerFrame);
474
475 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && byteSizePerFrame == sizePerFrameInByte_, ret, "ResolveBuffer failed"
476 ":%{public}d", ret);
477
478 clientSpanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame;
479
480 AUDIO_INFO_LOG("totalSizeInFrame_[%{public}u] spanSizeInFrame_[%{public}u] sizePerFrameInByte_["
481 "%{public}zu] clientSpanSizeInByte_[%{public}zu]", totalSizeInFrame, spanSizeInFrame_, sizePerFrameInByte_,
482 clientSpanSizeInByte_);
483
484 return SUCCESS;
485 }
486
487 // InitCacheBuffer should be able to modify the cache size between clientSpanSizeInByte_ and 4 * clientSpanSizeInByte_
InitCacheBuffer(size_t targetSize)488 int32_t CapturerInClientInner::InitCacheBuffer(size_t targetSize)
489 {
490 CHECK_AND_RETURN_RET_LOG(clientSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "clientSpanSizeInByte_ invalid");
491
492 AUDIO_INFO_LOG("old size:%{public}zu, new size:%{public}zu", cacheSizeInByte_, targetSize);
493 cacheSizeInByte_ = targetSize;
494
495 if (ringCache_ == nullptr) {
496 ringCache_ = AudioRingCache::Create(cacheSizeInByte_);
497 } else {
498 OptResult result = ringCache_->ReConfig(cacheSizeInByte_, false); // false --> clear buffer
499 if (result.ret != OPERATION_SUCCESS) {
500 AUDIO_ERR_LOG("ReConfig AudioRingCache to size %{public}u failed:ret%{public}zu", result.ret, targetSize);
501 return ERR_OPERATION_FAILED;
502 }
503 }
504
505 return SUCCESS;
506 }
507
InitIpcStream(const AudioPlaybackCaptureConfig & filterConfig)508 int32_t CapturerInClientInner::InitIpcStream(const AudioPlaybackCaptureConfig &filterConfig)
509 {
510 AUDIO_INFO_LOG("Init Ipc stream");
511 AudioProcessConfig config = ConstructConfig();
512
513 sptr<IStandardAudioService> gasp = CapturerInClientInner::GetAudioServerProxy();
514 CHECK_AND_RETURN_RET_LOG(gasp != nullptr, ERR_OPERATION_FAILED, "Create failed, can not get service.");
515 int32_t errorCode = 0;
516 sptr<IRemoteObject> ipcProxy = nullptr;
517 gasp->CreateAudioProcess(config, errorCode, filterConfig, ipcProxy);
518 for (int32_t retrycount = 0; (errorCode == ERR_RETRY_IN_CLIENT) && (retrycount < MAX_RETRY_COUNT); retrycount++) {
519 AUDIO_WARNING_LOG("retry in client");
520 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_WAIT_TIME_MS));
521 AudioPlaybackCaptureConfig defalutConfig = {};
522 gasp->CreateAudioProcess(config, errorCode, defalutConfig, ipcProxy);
523 }
524 CHECK_AND_RETURN_RET_LOG(errorCode == SUCCESS, errorCode, "failed with create audio stream fail.");
525 CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, ERR_OPERATION_FAILED, "failed with null ipcProxy.");
526 ipcStream_ = iface_cast<IIpcStream>(ipcProxy);
527 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "failed when iface_cast.");
528
529 // in plan: old listener_ is destoried here, will server receive dieth notify?
530 listener_ = sptr<IpcStreamListenerImpl>::MakeSptr(shared_from_this());
531 int32_t ret = ipcStream_->RegisterStreamListener(listener_->AsObject());
532 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RegisterStreamListener failed:%{public}d", ret);
533
534 ret = InitSharedBuffer();
535 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitSharedBuffer failed:%{public}d", ret);
536
537 ret = InitCacheBuffer(clientSpanSizeInByte_);
538 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitCacheBuffer failed:%{public}d", ret);
539
540 ret = ipcStream_->GetAudioSessionID(sessionId_);
541 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetAudioSessionID failed:%{public}d", ret);
542
543 InitCallbackHandler();
544 return SUCCESS;
545 }
546
GetAudioStreamInfo(AudioStreamParams & info)547 int32_t CapturerInClientInner::GetAudioStreamInfo(AudioStreamParams &info)
548 {
549 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, ERR_OPERATION_FAILED, "Params is not set");
550 info = streamParams_;
551 return SUCCESS;
552 }
553
GetAudioSessionID(uint32_t & sessionID)554 int32_t CapturerInClientInner::GetAudioSessionID(uint32_t &sessionID)
555 {
556 CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != NEW), ERR_ILLEGAL_STATE,
557 "State error %{public}d", state_.load());
558 sessionID = sessionId_;
559 return SUCCESS;
560 }
561
GetAudioPipeType(AudioPipeType & pipeType)562 void CapturerInClientInner::GetAudioPipeType(AudioPipeType &pipeType)
563 {
564 pipeType = capturerInfo_.pipeType;
565 }
566
GetState()567 State CapturerInClientInner::GetState()
568 {
569 return state_;
570 }
571
GetAudioTimeInner(Timestamp & timestamp,Timestamp::Timestampbase base,int64_t latency)572 bool CapturerInClientInner::GetAudioTimeInner(
573 Timestamp ×tamp, Timestamp::Timestampbase base, int64_t latency)
574 {
575 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
576 CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
577 uint64_t currentReadPos = totalBytesRead_ / sizePerFrameInByte_;
578 timestamp.framePosition = currentReadPos;
579
580 uint64_t writePos = 0;
581 int64_t handleTime = 0;
582 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
583 clientBuffer_->GetHandleInfo(writePos, handleTime);
584 if (writePos == 0 || handleTime == 0) {
585 AUDIO_WARNING_LOG("GetHandleInfo may failed");
586 }
587
588 int64_t deltaPos = writePos >= currentReadPos ? static_cast<int64_t>(writePos - currentReadPos) : 0;
589 int64_t deltaTime = deltaPos * AUDIO_MS_PER_SECOND /
590 static_cast<int64_t>(streamParams_.samplingRate) * AUDIO_US_PER_S;
591 handleTime = handleTime + deltaTime + latency;
592
593 timestamp.time.tv_sec = static_cast<time_t>(handleTime / AUDIO_NS_PER_SECOND);
594 timestamp.time.tv_nsec = static_cast<time_t>(handleTime % AUDIO_NS_PER_SECOND);
595
596 return true;
597 }
598
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)599 bool CapturerInClientInner::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base)
600 {
601 int64_t tempLatency = 25000000; // 25000000 -> 25 ms
602 return GetAudioTimeInner(timestamp, base, tempLatency);
603 }
604
GetTimeStampInfo(Timestamp & timestamp,Timestamp::Timestampbase base)605 bool CapturerInClientInner::GetTimeStampInfo(Timestamp ×tamp, Timestamp::Timestampbase base)
606 {
607 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
608 CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
609 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
610
611 if (capturerInfo_.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
612 return GetAudioTimeInner(timestamp, base, 0);
613 }
614
615 uint64_t writePos = 0;
616 uint64_t writeTimeStamp = 0;
617 clientBuffer_->GetTimeStampInfo(writePos, writeTimeStamp);
618 CHECK_AND_RETURN_RET_LOG(writeTimeStamp != 0, false, "writeTimeStamp is zero");
619 AUDIO_DEBUG_LOG("pos:%{public}" PRIu64 " ts:%{public}" PRIu64, writePos, writeTimeStamp);
620
621 timestamp.framePosition = writePos;
622 timestamp.time.tv_sec = static_cast<time_t>(writeTimeStamp / AUDIO_NS_PER_SECOND);
623 timestamp.time.tv_nsec = static_cast<time_t>(writeTimeStamp % AUDIO_NS_PER_SECOND);
624
625 return true;
626 }
627
GetAudioPosition(Timestamp & timestamp,Timestamp::Timestampbase base)628 bool CapturerInClientInner::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base)
629 {
630 return GetAudioTime(timestamp, base);
631 }
632
SetSwitchInfoTimestamp(std::vector<std::pair<uint64_t,uint64_t>> lastFramePosAndTimePair,std::vector<std::pair<uint64_t,uint64_t>> lastFramePosAndTimePairWithSpeed)633 void CapturerInClientInner::SetSwitchInfoTimestamp(
634 std::vector<std::pair<uint64_t, uint64_t>> lastFramePosAndTimePair,
635 std::vector<std::pair<uint64_t, uint64_t>> lastFramePosAndTimePairWithSpeed)
636 {
637 (void)lastFramePosAndTimePair;
638 (void)lastFramePosAndTimePairWithSpeed;
639 AUDIO_INFO_LOG("capturer stream not support timestamp re-set when stream switching");
640 }
641
GetBufferSize(size_t & bufferSize)642 int32_t CapturerInClientInner::GetBufferSize(size_t &bufferSize)
643 {
644 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Capturer stream is released");
645 bufferSize = clientSpanSizeInByte_;
646 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
647 bufferSize = cbBufferSize_;
648 }
649 AUDIO_DEBUG_LOG("Buffer size is %{public}zu, mode is %{public}s", bufferSize, capturerMode_ == CAPTURE_MODE_NORMAL ?
650 "CAPTURE_MODE_NORMAL" : "CAPTURE_MODE_CALLBACK");
651 return SUCCESS;
652 }
653
GetFrameCount(uint32_t & frameCount)654 int32_t CapturerInClientInner::GetFrameCount(uint32_t &frameCount)
655 {
656 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Capturer stream is released");
657 CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, ERR_ILLEGAL_STATE, "sizePerFrameInByte_ is 0!");
658 frameCount = spanSizeInFrame_;
659 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
660 frameCount = cbBufferSize_ / sizePerFrameInByte_;
661 }
662 AUDIO_INFO_LOG("Frame count is %{public}u, mode is %{public}s", frameCount, capturerMode_ == CAPTURE_MODE_NORMAL ?
663 "CAPTURE_MODE_NORMAL" : "CAPTURE_MODE_CALLBACK");
664 return SUCCESS;
665 }
666
GetLatency(uint64_t & latency)667 int32_t CapturerInClientInner::GetLatency(uint64_t &latency)
668 {
669 // GetLatency is never called in audio_capturer.cpp
670 latency = 150000; // unit is us, 150000 is 150ms
671 return ERROR;
672 }
673
SetAudioStreamType(AudioStreamType audioStreamType)674 int32_t CapturerInClientInner::SetAudioStreamType(AudioStreamType audioStreamType)
675 {
676 AUDIO_ERR_LOG("Change stream type %{public}d to %{public}d is not supported", eStreamType_, audioStreamType);
677 return ERROR;
678 }
679
SetVolume(float volume)680 int32_t CapturerInClientInner::SetVolume(float volume)
681 {
682 AUDIO_WARNING_LOG("SetVolume is only for renderer");
683 return ERROR;
684 }
685
GetVolume()686 float CapturerInClientInner::GetVolume()
687 {
688 AUDIO_WARNING_LOG("GetVolume is only for renderer");
689 return 0.0;
690 }
691
SetLoudnessGain(float loudnessGain)692 int32_t CapturerInClientInner::SetLoudnessGain(float loudnessGain)
693 {
694 AUDIO_WARNING_LOG("SetLoudnessGain is only for renderer");
695 return ERROR;
696 }
697
GetLoudnessGain()698 float CapturerInClientInner::GetLoudnessGain()
699 {
700 AUDIO_WARNING_LOG("GetLoudnessGain is only for renderer");
701 return 0.0;
702 }
703
SetMute(bool mute,StateChangeCmdType cmdType)704 int32_t CapturerInClientInner::SetMute(bool mute, StateChangeCmdType cmdType)
705 {
706 AUDIO_WARNING_LOG("only for renderer");
707 return ERROR;
708 }
709
GetMute()710 bool CapturerInClientInner::GetMute()
711 {
712 AUDIO_WARNING_LOG("only for renderer");
713 return false;
714 }
715
SetDuckVolume(float volume)716 int32_t CapturerInClientInner::SetDuckVolume(float volume)
717 {
718 AUDIO_WARNING_LOG("only for renderer");
719 return ERROR;
720 }
721
GetDuckVolume()722 float CapturerInClientInner::GetDuckVolume()
723 {
724 AUDIO_WARNING_LOG("only for renderer");
725 return ERROR_VOLUME;
726 }
727
SetSpeed(float speed)728 int32_t CapturerInClientInner::SetSpeed(float speed)
729 {
730 AUDIO_ERR_LOG("SetSpeed is not supported");
731 return ERROR;
732 }
733
SetPitch(float pitch)734 int32_t CapturerInClientInner::SetPitch(float pitch)
735 {
736 AUDIO_ERR_LOG("SetPitch is not supported");
737 return ERROR;
738 }
739
GetSpeed()740 float CapturerInClientInner::GetSpeed()
741 {
742 AUDIO_ERR_LOG("GetSpeed is not supported");
743 return 1.0;
744 }
745
SetRenderRate(AudioRendererRate renderRate)746 int32_t CapturerInClientInner::SetRenderRate(AudioRendererRate renderRate)
747 {
748 AUDIO_WARNING_LOG("SetRenderRate is only for renderer");
749 return ERROR;
750 }
751
GetRenderRate()752 AudioRendererRate CapturerInClientInner::GetRenderRate()
753 {
754 AUDIO_WARNING_LOG("GetRenderRate is only for renderer");
755 return RENDER_RATE_NORMAL; // not supported
756 }
757
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)758 int32_t CapturerInClientInner::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
759 {
760 if (callback == nullptr) {
761 AUDIO_ERR_LOG("SetStreamCallback failed. callback == nullptr");
762 return ERR_INVALID_PARAM;
763 }
764
765 std::unique_lock<std::mutex> lock(streamCbMutex_);
766 streamCallback_ = callback;
767 lock.unlock();
768
769 if (state_ != PREPARED) {
770 return SUCCESS;
771 }
772 SafeSendCallbackEvent(STATE_CHANGE_EVENT, PREPARED);
773 return SUCCESS;
774 }
775
SetRenderMode(AudioRenderMode renderMode)776 int32_t CapturerInClientInner::SetRenderMode(AudioRenderMode renderMode)
777 {
778 AUDIO_WARNING_LOG("SetRenderMode is only for renderer");
779 return ERROR;
780 }
781
GetRenderMode()782 AudioRenderMode CapturerInClientInner::GetRenderMode()
783 {
784 AUDIO_WARNING_LOG("GetRenderMode is only for renderer");
785 return RENDER_MODE_NORMAL; // not supported
786 }
787
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)788 int32_t CapturerInClientInner::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
789 {
790 AUDIO_WARNING_LOG("SetRendererWriteCallback is only for renderer");
791 return ERROR;
792 }
793
InitCallbackBuffer(uint64_t bufferDurationInUs)794 void CapturerInClientInner::InitCallbackBuffer(uint64_t bufferDurationInUs)
795 {
796 if (bufferDurationInUs > MAX_BUF_DURATION_IN_USEC) {
797 AUDIO_ERR_LOG("InitCallbackBuffer with invalid duration %{public}" PRIu64", use default instead.",
798 bufferDurationInUs);
799 bufferDurationInUs = DEFAULT_BUF_DURATION_IN_USEC;
800 }
801 // Calculate buffer size based on duration.
802 cbBufferSize_ = static_cast<size_t>(bufferDurationInUs * streamParams_.samplingRate / AUDIO_US_PER_S) *
803 sizePerFrameInByte_;
804 AUDIO_INFO_LOG("InitCallbackBuffer with duration %{public}" PRIu64", size: %{public}zu", bufferDurationInUs,
805 cbBufferSize_);
806 std::lock_guard<std::mutex> lock(cbBufferMutex_);
807 cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_);
808 BufferDesc temp = {cbBuffer_.get(), cbBufferSize_, cbBufferSize_};
809 cbBufferQueue_.Clear();
810 cbBufferQueue_.Push(temp);
811 }
812
InitCallbackLoop()813 void CapturerInClientInner::InitCallbackLoop()
814 {
815 cbThreadReleased_ = false;
816 auto weakRef = weak_from_this();
817
818 // OS_AudioWriteCB
819 ResetCallbackLoopTid();
820 callbackLoop_ = std::thread([weakRef] {
821 bool keepRunning = true;
822 std::shared_ptr<CapturerInClientInner> strongRef = weakRef.lock();
823 strongRef->SetCallbackLoopTid(gettid());
824 if (strongRef != nullptr) {
825 strongRef->cbThreadCv_.notify_one();
826 AUDIO_INFO_LOG("Thread start, sessionID :%{public}d", strongRef->sessionId_);
827 } else {
828 AUDIO_WARNING_LOG("Strong ref is nullptr, could cause error");
829 }
830 strongRef = nullptr;
831 // start loop
832 while (keepRunning) {
833 strongRef = weakRef.lock();
834 if (strongRef == nullptr) {
835 AUDIO_INFO_LOG("CapturerInClientInner destroyed");
836 break;
837 }
838 keepRunning = strongRef->ReadCallbackFunc(); // Main operation in callback loop
839 }
840 if (strongRef != nullptr) {
841 AUDIO_INFO_LOG("CBThread end sessionID :%{public}d", strongRef->sessionId_);
842 }
843 });
844 pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioReadCb");
845 }
846
SetCaptureMode(AudioCaptureMode captureMode)847 int32_t CapturerInClientInner::SetCaptureMode(AudioCaptureMode captureMode)
848 {
849 AUDIO_INFO_LOG("Set mode to %{public}s", captureMode == CAPTURE_MODE_NORMAL ? "CAPTURE_MODE_NORMAL" :
850 "CAPTURE_MODE_CALLBACK");
851 if (capturerMode_ == captureMode) {
852 return SUCCESS;
853 }
854
855 // capturerMode_ is inited as CAPTURE_MODE_NORMAL, can only be set to CAPTURE_MODE_CALLBACK.
856 if (capturerMode_ == CAPTURE_MODE_CALLBACK && captureMode == CAPTURE_MODE_NORMAL) {
857 AUDIO_ERR_LOG("Set capturer mode from callback to normal is not supported.");
858 return ERR_INCORRECT_MODE;
859 }
860
861 // state check
862 if (state_ != PREPARED && state_ != NEW) {
863 AUDIO_ERR_LOG("Set capturer mode failed. invalid state:%{public}d", state_.load());
864 return ERR_ILLEGAL_STATE;
865 }
866 capturerMode_ = captureMode;
867
868 // init callbackLoop_
869 InitCallbackLoop();
870
871 std::unique_lock<std::mutex> threadStartlock(statusMutex_);
872 bool stopWaiting = cbThreadCv_.wait_for(threadStartlock, std::chrono::milliseconds(SHORT_TIMEOUT_IN_MS), [this] {
873 return cbThreadReleased_ == false; // When thread is started, cbThreadReleased_ will be false. So stop waiting.
874 });
875 if (!stopWaiting) {
876 AUDIO_WARNING_LOG("Init OS_AudioReadCB thread time out");
877 }
878
879 CHECK_AND_RETURN_RET_LOG(streamParams_.samplingRate != 0, ERR_ILLEGAL_STATE, "invalid sample rate");
880
881 uint64_t bufferDurationInUs = spanSizeInFrame_ * AUDIO_US_PER_S / streamParams_.samplingRate;
882 InitCallbackBuffer(bufferDurationInUs);
883 return SUCCESS;
884 }
885
GetCaptureMode()886 AudioCaptureMode CapturerInClientInner::GetCaptureMode()
887 {
888 AUDIO_INFO_LOG("capturer mode is %{public}s", capturerMode_ == CAPTURE_MODE_NORMAL ? "CAPTURE_MODE_NORMAL" :
889 "CAPTURE_MODE_CALLBACK");
890 return capturerMode_;
891 }
892
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)893 int32_t CapturerInClientInner::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
894 {
895 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "Invalid null callback");
896 CHECK_AND_RETURN_RET_LOG(capturerMode_ == CAPTURE_MODE_CALLBACK, ERR_INCORRECT_MODE, "incorrect capturer mode");
897 std::lock_guard<std::mutex> lock(readCbMutex_);
898 readCb_ = callback;
899 return SUCCESS;
900 }
901
WaitForRunning()902 bool CapturerInClientInner::WaitForRunning()
903 {
904 Trace trace("CapturerInClientInner::WaitForRunning");
905 // check capturer state_: call client write only in running else wait on statusMutex_
906 std::unique_lock<std::mutex> stateLock(statusMutex_);
907 if (state_ != RUNNING) {
908 bool stopWaiting = cbThreadCv_.wait_for(stateLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
909 return state_ == RUNNING || cbThreadReleased_;
910 });
911 if (cbThreadReleased_) {
912 AUDIO_INFO_LOG("CBThread end in non-running status, sessionID :%{public}d", sessionId_);
913 return false;
914 }
915 if (!stopWaiting) {
916 AUDIO_INFO_LOG("Wait timeout, current state_ is %{public}d", state_.load()); // wait 0.5s
917 return false;
918 }
919 }
920 return true;
921 }
922
ReadCallbackFunc()923 bool CapturerInClientInner::ReadCallbackFunc()
924 {
925 if (cbThreadReleased_) {
926 return false;
927 }
928 Trace traceLoop("CapturerInClientInner::WriteCallbackFunc");
929 if (!WaitForRunning()) {
930 return true;
931 }
932
933 // If client didn't call GetBufferDesc/Enqueue in OnReadData, pop will block here.
934 BufferDesc temp = cbBufferQueue_.Pop();
935 if (temp.buffer == nullptr) {
936 AUDIO_WARNING_LOG("Queue pop error: get nullptr.");
937 return false;
938 }
939
940 std::unique_lock<std::mutex> lockBuffer(cbBufferMutex_);
941 // call read here.
942 int32_t result = Read(*temp.buffer, temp.bufLength, true); // blocking read
943 if (result < 0 || result != static_cast<int32_t>(cbBufferSize_)) {
944 AUDIO_WARNING_LOG("Call read error, ret:%{public}d, cbBufferSize_:%{public}zu", result, cbBufferSize_);
945 }
946 if (state_ != RUNNING) {
947 return true;
948 }
949 lockBuffer.unlock();
950
951 // call client read
952 Trace traceCb("CapturerInClientInner::OnReadData");
953 std::unique_lock<std::mutex> lockCb(readCbMutex_);
954 if (readCb_ != nullptr) {
955 readCb_->OnReadData(cbBufferSize_);
956 }
957 lockCb.unlock();
958 traceCb.End();
959 return true;
960 }
961
962
GetBufferDesc(BufferDesc & bufDesc)963 int32_t CapturerInClientInner::GetBufferDesc(BufferDesc &bufDesc)
964 {
965 Trace trace("CapturerInClientInner::GetBufferDesc");
966 if (capturerMode_ != CAPTURE_MODE_CALLBACK) {
967 AUDIO_ERR_LOG("Not supported. mode is not callback.");
968 return ERR_INCORRECT_MODE;
969 }
970 std::lock_guard<std::mutex> lock(cbBufferMutex_);
971 bufDesc.buffer = cbBuffer_.get();
972 bufDesc.bufLength = cbBufferSize_;
973 bufDesc.dataLength = cbBufferSize_;
974 return SUCCESS;
975 }
976
GetBufQueueState(BufferQueueState & bufState)977 int32_t CapturerInClientInner::GetBufQueueState(BufferQueueState &bufState)
978 {
979 Trace trace("CapturerInClientInner::GetBufQueueState");
980 if (capturerMode_ != CAPTURE_MODE_CALLBACK) {
981 AUDIO_ERR_LOG("Not supported, mode is not callback.");
982 return ERR_INCORRECT_MODE;
983 }
984 // only one buffer in queue.
985 bufState.numBuffers = 1;
986 bufState.currentIndex = 0;
987 return SUCCESS;
988 }
989
Enqueue(const BufferDesc & bufDesc)990 int32_t CapturerInClientInner::Enqueue(const BufferDesc &bufDesc)
991 {
992 Trace trace("CapturerInClientInner::Enqueue");
993 if (capturerMode_ != CAPTURE_MODE_CALLBACK) {
994 AUDIO_ERR_LOG("Not supported, mode is not callback.");
995 return ERR_INCORRECT_MODE;
996 }
997 std::lock_guard<std::mutex> lock(cbBufferMutex_);
998
999 if (bufDesc.bufLength != cbBufferSize_ || bufDesc.dataLength != cbBufferSize_) {
1000 AUDIO_ERR_LOG("Enqueue invalid bufLength:%{public}zu or dataLength:%{public}zu, should be %{public}zu",
1001 bufDesc.bufLength, bufDesc.dataLength, cbBufferSize_);
1002 return ERR_INVALID_INDEX;
1003 }
1004 if (bufDesc.buffer != cbBuffer_.get()) {
1005 AUDIO_WARNING_LOG("Enqueue buffer is not from us.");
1006 }
1007
1008 // if Enqueue is not called in OnReadData, loop thread will block on pop, wait for the Push call here.
1009 BufferDesc temp = {cbBuffer_.get(), cbBufferSize_, cbBufferSize_};
1010 cbBufferQueue_.Push(temp);
1011 // Call read may block, so put it in loop callbackLoop_
1012 return SUCCESS;
1013 }
1014
Clear()1015 int32_t CapturerInClientInner::Clear()
1016 {
1017 Trace trace("CapturerInClientInner::Clear");
1018 if (capturerMode_ != CAPTURE_MODE_CALLBACK) {
1019 AUDIO_ERR_LOG("Not supported, mode is not callback.");
1020 return ERR_INCORRECT_MODE;
1021 }
1022 std::lock_guard<std::mutex> lock(cbBufferMutex_);
1023 int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
1024 CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
1025 return SUCCESS;
1026 }
1027
SetLowPowerVolume(float volume)1028 int32_t CapturerInClientInner::SetLowPowerVolume(float volume)
1029 {
1030 AUDIO_WARNING_LOG("SetLowPowerVolume is only for renderer");
1031 return ERROR;
1032 }
1033
GetLowPowerVolume()1034 float CapturerInClientInner::GetLowPowerVolume()
1035 {
1036 AUDIO_WARNING_LOG("GetLowPowerVolume is only for renderer");
1037 return 0.0;
1038 }
1039
SetOffloadMode(int32_t state,bool isAppBack)1040 int32_t CapturerInClientInner::SetOffloadMode(int32_t state, bool isAppBack)
1041 {
1042 AUDIO_WARNING_LOG("SetOffloadMode is only for renderer");
1043 return ERROR;
1044 }
1045
UnsetOffloadMode()1046 int32_t CapturerInClientInner::UnsetOffloadMode()
1047 {
1048 AUDIO_WARNING_LOG("UnsetOffloadMode is only for renderer");
1049 return ERROR;
1050 }
1051
GetSingleStreamVolume()1052 float CapturerInClientInner::GetSingleStreamVolume()
1053 {
1054 AUDIO_WARNING_LOG("GetSingleStreamVolume is only for renderer");
1055 return 0.0;
1056 }
1057
GetAudioEffectMode()1058 AudioEffectMode CapturerInClientInner::GetAudioEffectMode()
1059 {
1060 AUDIO_WARNING_LOG("GetAudioEffectMode is only for renderer");
1061 return EFFECT_NONE;
1062 }
1063
SetAudioEffectMode(AudioEffectMode effectMode)1064 int32_t CapturerInClientInner::SetAudioEffectMode(AudioEffectMode effectMode)
1065 {
1066 AUDIO_WARNING_LOG("SetAudioEffectMode is only for renderer");
1067 return ERROR;
1068 }
1069
GetFramesWritten()1070 int64_t CapturerInClientInner::GetFramesWritten()
1071 {
1072 AUDIO_WARNING_LOG("GetFramesWritten is only for renderer");
1073 return -1;
1074 }
1075
GetFramesRead()1076 int64_t CapturerInClientInner::GetFramesRead()
1077 {
1078 CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, INVALID_FRAME_SIZE, "sizePerFrameInByte_ is 0!");
1079 uint64_t readFrameNumber = totalBytesRead_ / sizePerFrameInByte_;
1080 return readFrameNumber;
1081 }
1082
1083 // Will only take effect before SetAudioStreaminfo
SetInnerCapturerState(bool isInnerCapturer)1084 void CapturerInClientInner::SetInnerCapturerState(bool isInnerCapturer)
1085 {
1086 isInnerCapturer_ = isInnerCapturer;
1087 AUDIO_INFO_LOG("SetInnerCapturerState %{public}s", (isInnerCapturer_ ? "true" : "false"));
1088 return;
1089 }
1090
1091 // Will only take effect before SetAudioStreaminfo
SetWakeupCapturerState(bool isWakeupCapturer)1092 void CapturerInClientInner::SetWakeupCapturerState(bool isWakeupCapturer)
1093 {
1094 isWakeupCapturer_ = isWakeupCapturer;
1095 AUDIO_INFO_LOG("SetWakeupCapturerState %{public}s", (isWakeupCapturer_ ? "true" : "false"));
1096 return;
1097 }
1098
SetCapturerSource(int capturerSource)1099 void CapturerInClientInner::SetCapturerSource(int capturerSource)
1100 {
1101 // capturerSource is kept in capturerInfo_, no need to be set again.
1102 (void)capturerSource;
1103 return;
1104 }
1105
SetPrivacyType(AudioPrivacyType privacyType)1106 void CapturerInClientInner::SetPrivacyType(AudioPrivacyType privacyType)
1107 {
1108 AUDIO_WARNING_LOG("SetPrivacyType is only for renderer");
1109 return;
1110 }
1111
StartAudioStream(StateChangeCmdType cmdType,AudioStreamDeviceChangeReasonExt reason)1112 bool CapturerInClientInner::StartAudioStream(StateChangeCmdType cmdType, AudioStreamDeviceChangeReasonExt reason)
1113 {
1114 Trace trace("CapturerInClientInner::StartAudioStream " + std::to_string(sessionId_));
1115 std::unique_lock<std::mutex> statusLock(statusMutex_);
1116 if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) {
1117 AUDIO_ERR_LOG("Start failed Illegal state: %{public}d", state_.load());
1118 return false;
1119 }
1120
1121 if (audioStreamTracker_ && audioStreamTracker_.get()) {
1122 audioStreamTracker_->FetchInputDeviceForTrack(sessionId_, RUNNING, clientPid_, capturerInfo_);
1123 }
1124
1125 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1126 int32_t ret = ipcStream_->Start();
1127 if (ret != SUCCESS) {
1128 AUDIO_ERR_LOG("Start call server failed: %{public}u", ret);
1129 return false;
1130 }
1131
1132 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1133 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1134 return notifiedOperation_ == START_STREAM; // will be false when got notified.
1135 });
1136
1137 if (notifiedOperation_ != START_STREAM || notifiedResult_ != SUCCESS) {
1138 AUDIO_ERR_LOG("Start failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1139 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1140 return false;
1141 }
1142 waitLock.unlock();
1143
1144 state_ = RUNNING; // change state_ to RUNNING, then notify cbThread
1145 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
1146 if (cbBufferQueue_.IsEmpty()) {
1147 cbBufferQueue_.Push({cbBuffer_.get(), cbBufferSize_, cbBufferSize_});
1148 }
1149 // start the callback-write thread
1150 cbThreadCv_.notify_all();
1151 }
1152 statusLock.unlock();
1153 // in plan: call HiSysEventWrite
1154 int64_t param = -1;
1155 StateCmdTypeToParams(param, state_, cmdType);
1156 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1157
1158 AUDIO_INFO_LOG("Start SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1159 UpdateTracker("RUNNING");
1160 return true;
1161 }
1162
PauseAudioStream(StateChangeCmdType cmdType)1163 bool CapturerInClientInner::PauseAudioStream(StateChangeCmdType cmdType)
1164 {
1165 Trace trace("CapturerInClientInner::PauseAudioStream " + std::to_string(sessionId_));
1166 std::unique_lock<std::mutex> statusLock(statusMutex_);
1167 if (state_ != RUNNING) {
1168 AUDIO_ERR_LOG("Pause State is not RUNNING. Illegal state:%{public}u", state_.load());
1169 return false;
1170 }
1171
1172 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1173 int32_t ret = ipcStream_->Pause();
1174 if (ret != SUCCESS) {
1175 AUDIO_ERR_LOG("Pause call server failed:%{public}u", ret);
1176 return false;
1177 }
1178 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1179 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1180 return notifiedOperation_ == PAUSE_STREAM; // will be false when got notified.
1181 });
1182
1183 if (notifiedOperation_ != PAUSE_STREAM || notifiedResult_ != SUCCESS) {
1184 AUDIO_ERR_LOG("Pause failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1185 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1186 return false;
1187 }
1188 waitLock.unlock();
1189
1190 state_ = PAUSED;
1191 statusLock.unlock();
1192
1193 // waiting for review: use send event to clent with cmdType | call OnStateChange | call HiSysEventWrite
1194 int64_t param = -1;
1195 StateCmdTypeToParams(param, state_, cmdType);
1196 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1197
1198 AUDIO_INFO_LOG("Pause SUCCESS, sessionId: %{public}d, uid: %{public}d, mode %{public}s", sessionId_, clientUid_,
1199 capturerMode_ == CAPTURE_MODE_NORMAL ? "CAPTURE_MODE_NORMAL" : "CAPTURE_MODE_CALLBACK");
1200 UpdateTracker("PAUSED");
1201 return true;
1202 }
1203
StopAudioStream()1204 bool CapturerInClientInner::StopAudioStream()
1205 {
1206 Trace trace("CapturerInClientInner::StopAudioStream " + std::to_string(sessionId_));
1207 AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1208 std::unique_lock<std::mutex> statusLock(statusMutex_);
1209 if (state_ == STOPPED) {
1210 AUDIO_INFO_LOG("Capturer in client is already stopped");
1211 return true;
1212 }
1213 if ((state_ != RUNNING) && (state_ != PAUSED)) {
1214 AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load());
1215 return false;
1216 }
1217
1218 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1219 int32_t ret = ipcStream_->Stop();
1220 if (ret != SUCCESS) {
1221 AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret);
1222 return false;
1223 }
1224
1225 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
1226 state_ = STOPPING;
1227 readDataCV_.notify_all();
1228 AUDIO_INFO_LOG("Stop begin in callback mode sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1229 }
1230
1231 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1232 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1233 return notifiedOperation_ == STOP_STREAM; // will be false when got notified.
1234 });
1235
1236 if (notifiedOperation_ != STOP_STREAM || notifiedResult_ != SUCCESS) {
1237 AUDIO_ERR_LOG("Stop failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1238 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1239 state_ = INVALID;
1240 return false;
1241 }
1242 waitLock.unlock();
1243
1244 state_ = STOPPED;
1245 statusLock.unlock();
1246
1247 SafeSendCallbackEvent(STATE_CHANGE_EVENT, state_);
1248
1249 AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1250 UpdateTracker("STOPPED");
1251 return true;
1252 }
1253
ReleaseAudioStream(bool releaseRunner,bool isSwitchStream)1254 bool CapturerInClientInner::ReleaseAudioStream(bool releaseRunner, bool isSwitchStream)
1255 {
1256 std::unique_lock<std::mutex> statusLock(statusMutex_);
1257 if (state_ == RELEASED) {
1258 AUDIO_WARNING_LOG("Already release, do nothing");
1259 return true;
1260 }
1261 state_ = RELEASED;
1262 statusLock.unlock();
1263
1264 Trace trace("CapturerInClientInner::ReleaseAudioStream " + std::to_string(sessionId_));
1265 if (ipcStream_ != nullptr) {
1266 ipcStream_->Release(isSwitchStream);
1267 } else {
1268 AUDIO_WARNING_LOG("Release while ipcStream is null");
1269 }
1270
1271 // no lock, call release in any case, include blocked case.
1272 {
1273 std::lock_guard<std::mutex> runnerlock(runnerMutex_);
1274 if (releaseRunner && callbackHandler_ != nullptr) {
1275 AUDIO_INFO_LOG("runner remove");
1276 callbackHandler_->ReleaseEventRunner();
1277 runnerReleased_ = true;
1278 callbackHandler_ = nullptr;
1279 }
1280 }
1281
1282 // clear write callback
1283 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
1284 cbThreadReleased_ = true; // stop loop
1285 if (cbBufferQueue_.IsEmpty()) {
1286 cbBufferQueue_.PushNoWait({nullptr, 0, 0});
1287 }
1288 cbThreadCv_.notify_all();
1289 readDataCV_.notify_all();
1290 if (callbackLoop_.joinable()) {
1291 callbackLoop_.join();
1292 }
1293 }
1294 paramsIsSet_ = false;
1295
1296 std::unique_lock<std::mutex> lock(streamCbMutex_);
1297 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1298 if (streamCb != nullptr) {
1299 AUDIO_INFO_LOG("Notify client the state is released");
1300 streamCb->OnStateChange(RELEASED, CMD_FROM_CLIENT);
1301 }
1302 lock.unlock();
1303
1304 UpdateTracker("RELEASED");
1305 AUDIO_INFO_LOG("Release end, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1306 return true;
1307 }
1308
FlushAudioStream()1309 bool CapturerInClientInner::FlushAudioStream()
1310 {
1311 Trace trace("CapturerInClientInner::FlushAudioStream " + std::to_string(sessionId_));
1312 std::unique_lock<std::mutex> statusLock(statusMutex_);
1313 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
1314 AUDIO_ERR_LOG("Flush failed. Illegal state:%{public}u", state_.load());
1315 return false;
1316 }
1317 CHECK_AND_RETURN_RET_LOG(FlushRingCache() == SUCCESS, false, "Flush ringCache failed");
1318 CHECK_AND_RETURN_RET_LOG(FlushCbBuffer() == SUCCESS, false, "Flush cbBuffer failed");
1319
1320 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1321 int32_t ret = ipcStream_->Flush();
1322 if (ret != SUCCESS) {
1323 AUDIO_ERR_LOG("Flush call server failed:%{public}u", ret);
1324 return false;
1325 }
1326 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1327 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1328 return notifiedOperation_ == FLUSH_STREAM; // will be false when got notified.
1329 });
1330
1331 if (notifiedOperation_ != FLUSH_STREAM || notifiedResult_ != SUCCESS) {
1332 AUDIO_ERR_LOG("Flush failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1333 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1334 notifiedOperation_ = MAX_OPERATION_CODE;
1335 return false;
1336 }
1337 notifiedOperation_ = MAX_OPERATION_CODE;
1338 waitLock.unlock();
1339 AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
1340 return true;
1341 }
1342
FlushRingCache()1343 int32_t CapturerInClientInner::FlushRingCache()
1344 {
1345 ringCache_->ResetBuffer();
1346 return SUCCESS;
1347 }
1348
FlushCbBuffer()1349 int32_t CapturerInClientInner::FlushCbBuffer()
1350 {
1351 Trace trace("CapturerInClientInner::FlushCbBuffer");
1352 if (cbBuffer_ != nullptr && capturerMode_ == CAPTURE_MODE_CALLBACK) {
1353 std::lock_guard<std::mutex> lock(cbBufferMutex_);
1354 int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
1355 CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
1356 AUDIO_INFO_LOG("Flush cbBuffer_ for sessionId:%{public}d uid:%{public}d, ret:%{public}d",
1357 sessionId_, clientUid_, ret);
1358 }
1359 return SUCCESS;
1360 }
1361
DrainAudioStream(bool stopFlag)1362 bool CapturerInClientInner::DrainAudioStream(bool stopFlag)
1363 {
1364 AUDIO_ERR_LOG("Drain is not supported");
1365 return false;
1366 }
1367
SetPreferredFrameSize(int32_t frameSize)1368 void CapturerInClientInner::SetPreferredFrameSize(int32_t frameSize)
1369 {
1370 AUDIO_WARNING_LOG("Not Supported Yet");
1371 }
1372
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)1373 void CapturerInClientInner::UpdateLatencyTimestamp(std::string ×tamp, bool isRenderer)
1374 {
1375 sptr<IStandardAudioService> gasp = CapturerInClientInner::GetAudioServerProxy();
1376 if (gasp == nullptr) {
1377 AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
1378 return;
1379 }
1380 gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
1381 }
1382
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)1383 int32_t CapturerInClientInner::SetRendererFirstFrameWritingCallback(
1384 const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
1385 {
1386 AUDIO_ERR_LOG("SetRendererFirstFrameWritingCallback is not supported for capturer");
1387 return ERR_INVALID_OPERATION;
1388 }
1389
OnFirstFrameWriting()1390 void CapturerInClientInner::OnFirstFrameWriting()
1391 {
1392 AUDIO_ERR_LOG("OnFirstFrameWriting is not supported for capturer");
1393 }
1394
Write(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1395 int32_t CapturerInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1396 size_t metaBufferSize)
1397 {
1398 AUDIO_ERR_LOG("Write is not supported");
1399 return ERR_INVALID_OPERATION;
1400 }
1401
Write(uint8_t * buffer,size_t bufferSize)1402 int32_t CapturerInClientInner::Write(uint8_t *buffer, size_t bufferSize)
1403 {
1404 AUDIO_ERR_LOG("Write is not supported");
1405 return ERR_INVALID_OPERATION;
1406 }
1407
HandleCapturerRead(size_t & readSize,size_t & userSize,uint8_t & buffer,bool isBlockingRead)1408 int32_t CapturerInClientInner::HandleCapturerRead(size_t &readSize, size_t &userSize, uint8_t &buffer,
1409 bool isBlockingRead)
1410 {
1411 Trace trace("CapturerInClientInner::HandleCapturerRead " + std::to_string(userSize));
1412 while (readSize < userSize) {
1413 AUDIO_DEBUG_LOG("readSize %{public}zu < userSize %{public}zu", readSize, userSize);
1414 OptResult result = ringCache_->GetReadableSize();
1415 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "GetReadableSize err %{public}d", result.ret);
1416 size_t readableSize = std::min(result.size, userSize - readSize);
1417 if (readSize + result.size >= userSize) { // If ringCache is sufficient
1418 result = ringCache_->Dequeue({&buffer + (readSize), readableSize});
1419 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "DequeueCache err %{public}d", result.ret);
1420 readSize += readableSize;
1421 return readSize; // data size
1422 }
1423 if (result.size != 0) {
1424 result = ringCache_->Dequeue({&buffer + readSize, result.size});
1425 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "Dequeue failed %{public}d", result.ret);
1426 readSize += result.size;
1427 }
1428 uint64_t availableSizeInFrame = clientBuffer_->GetCurWriteFrame() - clientBuffer_->GetCurReadFrame();
1429 AUDIO_DEBUG_LOG("availableSizeInFrame %{public}" PRId64 "", availableSizeInFrame);
1430 if (availableSizeInFrame > 0) { // If OHAudioBuffer has data
1431 BufferDesc currentOHBuffer_ = {};
1432 clientBuffer_->GetTimeStampInfo(currentOHBuffer_.position, currentOHBuffer_.timeStampInNs);
1433 clientBuffer_->GetReadbuffer(clientBuffer_->GetCurReadFrame(), currentOHBuffer_);
1434 BufferWrap bufferWrap = {currentOHBuffer_.buffer, clientSpanSizeInByte_};
1435 ringCache_->Enqueue(bufferWrap);
1436 memset_s(static_cast<void *>(bufferWrap.dataPtr), bufferWrap.dataSize, 0, bufferWrap.dataSize);
1437 clientBuffer_->SetCurReadFrame((clientBuffer_->GetCurReadFrame() + spanSizeInFrame_), false);
1438 } else {
1439 if (!isBlockingRead) {
1440 return readSize; // Return buffer immediately
1441 }
1442 // wait for server read some data
1443 std::unique_lock<std::mutex> readLock(readDataMutex_);
1444 bool isTimeout = !readDataCV_.wait_for(readLock,
1445 std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1446 return clientBuffer_->GetCurWriteFrame() > clientBuffer_->GetCurReadFrame() || state_ != RUNNING;
1447 });
1448 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "State is not running");
1449 CHECK_AND_RETURN_RET_LOG(isTimeout == false, ERROR, "Wait timeout");
1450 }
1451 }
1452 return readSize;
1453 }
1454
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)1455 int32_t CapturerInClientInner::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
1456 {
1457 Trace trace("CapturerInClientInner::Read " + std::to_string(userSize));
1458
1459 CHECK_AND_RETURN_RET_LOG(userSize < MAX_CLIENT_READ_SIZE && userSize > 0,
1460 ERR_INVALID_PARAM, "invalid size %{public}zu", userSize);
1461
1462 std::unique_lock<std::mutex> statusLock(statusMutex_); // status check
1463 if (state_ != RUNNING) {
1464 if (readLogTimes_ < LOGLITMITTIMES) {
1465 readLogTimes_.fetch_add(1);
1466 AUDIO_ERR_LOG("Illegal state:%{public}u", state_.load());
1467 } else {
1468 AUDIO_DEBUG_LOG("Illegal state:%{public}u", state_.load());
1469 }
1470 return ERR_ILLEGAL_STATE;
1471 } else {
1472 readLogTimes_ = 0;
1473 }
1474
1475 statusLock.unlock();
1476
1477 std::lock_guard<std::mutex> lock(readMutex_);
1478 // if first call, call set thread priority. if thread tid change recall set thread priority
1479 if (needSetThreadPriority_) {
1480 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERROR, "ipcStream_ is null");
1481 ipcStream_->RegisterThreadPriority(gettid(),
1482 AudioSystemManager::GetInstance()->GetSelfBundleName(clientConfig_.appInfo.appUid), METHOD_WRITE_OR_READ);
1483 needSetThreadPriority_ = false;
1484 }
1485
1486 size_t readSize = 0;
1487 int32_t res = HandleCapturerRead(readSize, userSize, buffer, isBlockingRead);
1488 CHECK_AND_RETURN_RET_LOG(res >= 0, ERROR, "HandleCapturerRead err : %{public}d", res);
1489 BufferDesc tmpBuffer = {reinterpret_cast<uint8_t *>(&buffer), userSize, userSize};
1490 VolumeTools::DfxOperation(tmpBuffer, clientConfig_.streamInfo, logUtilsTag_, volumeDataCount_);
1491 HandleCapturerPositionChanges(readSize);
1492 return readSize;
1493 }
1494
HandleCapturerPositionChanges(size_t bytesRead)1495 void CapturerInClientInner::HandleCapturerPositionChanges(size_t bytesRead)
1496 {
1497 totalBytesRead_ += bytesRead;
1498 if (sizePerFrameInByte_ == 0) {
1499 AUDIO_ERR_LOG("HandleCapturerPositionChanges: sizePerFrameInByte_ is 0");
1500 return;
1501 }
1502 uint64_t readFrameNumber = totalBytesRead_ / sizePerFrameInByte_;
1503 AUDIO_DEBUG_LOG("totalBytesRead_ %{public}" PRId64 ", frame size: %{public}zu", totalBytesRead_,
1504 sizePerFrameInByte_);
1505 {
1506 std::lock_guard<std::mutex> lock(markReachMutex_);
1507 if (!capturerMarkReached_) {
1508 AUDIO_DEBUG_LOG("Frame mark position: %{public}" PRId64 ", Total frames read: %{public}" PRId64,
1509 capturerMarkPosition_, static_cast<int64_t>(readFrameNumber));
1510 if (readFrameNumber >= static_cast<uint64_t>(capturerMarkPosition_)) {
1511 AUDIO_DEBUG_LOG("capturerInClient OnMarkReached");
1512 SendCapturerMarkReachedEvent(capturerMarkPosition_);
1513 capturerMarkReached_ = true;
1514 }
1515 }
1516 }
1517
1518 {
1519 std::lock_guard<std::mutex> lock(periodReachMutex_);
1520 capturerPeriodRead_ += static_cast<int64_t>(bytesRead / sizePerFrameInByte_);
1521 AUDIO_DEBUG_LOG("Frame period number: %{public}" PRId64 ", Total frames written: %{public}" PRId64,
1522 static_cast<int64_t>(capturerPeriodRead_), static_cast<int64_t>(totalBytesRead_));
1523 if (capturerPeriodRead_ >= capturerPeriodSize_ && capturerPeriodSize_ > 0) {
1524 capturerPeriodRead_ %= capturerPeriodSize_;
1525 AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRId64,
1526 static_cast<int64_t>(capturerPeriodRead_));
1527 SendCapturerPeriodReachedEvent(capturerPeriodSize_);
1528 }
1529 }
1530 }
1531
GetUnderflowCount()1532 uint32_t CapturerInClientInner::GetUnderflowCount()
1533 {
1534 // not supported for capturer
1535 AUDIO_WARNING_LOG("No Underflow in Capturer");
1536 return 0;
1537 }
1538
GetOverflowCount()1539 uint32_t CapturerInClientInner::GetOverflowCount()
1540 {
1541 return overflowCount_;
1542 }
1543
SetUnderflowCount(uint32_t underflowCount)1544 void CapturerInClientInner::SetUnderflowCount(uint32_t underflowCount)
1545 {
1546 // not supported for capturer
1547 AUDIO_WARNING_LOG("No Underflow in Capturer");
1548 return;
1549 }
1550
SetOverflowCount(uint32_t overflowCount)1551 void CapturerInClientInner::SetOverflowCount(uint32_t overflowCount)
1552 {
1553 overflowCount_ = overflowCount;
1554 }
1555
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)1556 void CapturerInClientInner::SetCapturerPositionCallback(int64_t markPosition, const
1557 std::shared_ptr<CapturerPositionCallback> &callback)
1558 {
1559 std::lock_guard<std::mutex> lock(markReachMutex_);
1560 CHECK_AND_RETURN_LOG(callback != nullptr, "CapturerPositionCallback is nullptr");
1561 capturerPositionCallback_ = callback;
1562 capturerMarkPosition_ = markPosition;
1563 capturerMarkReached_ = false;
1564 }
1565
UnsetCapturerPositionCallback()1566 void CapturerInClientInner::UnsetCapturerPositionCallback()
1567 {
1568 std::lock_guard<std::mutex> lock(markReachMutex_);
1569 capturerPositionCallback_ = nullptr;
1570 capturerMarkPosition_ = 0;
1571 capturerMarkReached_ = false;
1572 }
1573
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)1574 void CapturerInClientInner::SetCapturerPeriodPositionCallback(int64_t periodPosition,
1575 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
1576 {
1577 std::lock_guard<std::mutex> lock(periodReachMutex_);
1578 CHECK_AND_RETURN_LOG(callback != nullptr, "CapturerPeriodPositionCallback is nullptr");
1579 capturerPeriodPositionCallback_ = callback;
1580 capturerPeriodSize_ = periodPosition;
1581 totalBytesRead_ = 0;
1582 capturerPeriodRead_ = 0;
1583 }
1584
UnsetCapturerPeriodPositionCallback()1585 void CapturerInClientInner::UnsetCapturerPeriodPositionCallback()
1586 {
1587 std::lock_guard<std::mutex> lock(periodReachMutex_);
1588 capturerPeriodPositionCallback_ = nullptr;
1589 capturerPeriodSize_ = 0;
1590 totalBytesRead_ = 0;
1591 capturerPeriodRead_ = 0;
1592 }
1593
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1594 void CapturerInClientInner::SetRendererPositionCallback(int64_t markPosition,
1595 const std::shared_ptr<RendererPositionCallback> &callback)
1596 {
1597 AUDIO_ERR_LOG("SetRendererPositionCallback is not supported");
1598 return;
1599 }
1600
UnsetRendererPositionCallback()1601 void CapturerInClientInner::UnsetRendererPositionCallback()
1602 {
1603 AUDIO_ERR_LOG("UnsetRendererPositionCallback is not supported");
1604 return;
1605 }
1606
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)1607 void CapturerInClientInner::SetRendererPeriodPositionCallback(int64_t periodPosition,
1608 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
1609 {
1610 AUDIO_ERR_LOG("SetRendererPeriodPositionCallback is not supported");
1611 return;
1612 }
1613
UnsetRendererPeriodPositionCallback()1614 void CapturerInClientInner::UnsetRendererPeriodPositionCallback()
1615 {
1616 AUDIO_ERR_LOG("UnsetRendererPeriodPositionCallback is not supported");
1617 return;
1618 }
1619
SetRendererSamplingRate(uint32_t sampleRate)1620 int32_t CapturerInClientInner::SetRendererSamplingRate(uint32_t sampleRate)
1621 {
1622 // in plan
1623 return ERROR;
1624 }
1625
GetRendererSamplingRate()1626 uint32_t CapturerInClientInner::GetRendererSamplingRate()
1627 {
1628 // in plan
1629 return 0; // not supported
1630 }
1631
SetBufferSizeInMsec(int32_t bufferSizeInMsec)1632 int32_t CapturerInClientInner::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
1633 {
1634 // bufferSizeInMsec is checked between 5ms and 20ms.
1635 bufferSizeInMsec_ = bufferSizeInMsec;
1636 AUDIO_INFO_LOG("SetBufferSizeInMsec to %{public}d", bufferSizeInMsec_);
1637 if (capturerMode_ == CAPTURE_MODE_CALLBACK) {
1638 uint64_t bufferDurationInUs = static_cast<uint64_t>(bufferSizeInMsec_ * AUDIO_US_PER_MS);
1639 InitCallbackBuffer(bufferDurationInUs);
1640 }
1641 return SUCCESS;
1642 }
1643
SetChannelBlendMode(ChannelBlendMode blendMode)1644 int32_t CapturerInClientInner::SetChannelBlendMode(ChannelBlendMode blendMode)
1645 {
1646 AUDIO_WARNING_LOG("not supported in capturer");
1647 return ERROR;
1648 }
1649
SetVolumeWithRamp(float volume,int32_t duration)1650 int32_t CapturerInClientInner::SetVolumeWithRamp(float volume, int32_t duration)
1651 {
1652 AUDIO_WARNING_LOG("not supported in capturer");
1653 return ERROR;
1654 }
1655
SetStreamTrackerState(bool trackerRegisteredState)1656 void CapturerInClientInner::SetStreamTrackerState(bool trackerRegisteredState)
1657 {
1658 streamTrackerRegistered_ = trackerRegisteredState;
1659 }
1660
GetSwitchInfo(IAudioStream::SwitchInfo & info)1661 void CapturerInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info)
1662 {
1663 info.params = streamParams_;
1664
1665 info.rendererInfo = rendererInfo_;
1666 info.capturerInfo = capturerInfo_;
1667 info.eStreamType = eStreamType_;
1668 info.state = state_;
1669 info.sessionId = sessionId_;
1670 info.streamTrackerRegistered = streamTrackerRegistered_;
1671 GetStreamSwitchInfo(info);
1672 }
1673
GetStreamSwitchInfo(IAudioStream::SwitchInfo & info)1674 void CapturerInClientInner::GetStreamSwitchInfo(IAudioStream::SwitchInfo& info)
1675 {
1676 info.overFlowCount = overflowCount_;
1677 info.clientPid = clientPid_;
1678 info.clientUid = clientUid_;
1679
1680 info.frameMarkPosition = static_cast<uint64_t>(capturerMarkPosition_);
1681 info.capturePositionCb = capturerPositionCallback_;
1682
1683 info.framePeriodNumber = static_cast<uint64_t>(capturerPeriodSize_);
1684 info.capturePeriodPositionCb = capturerPeriodPositionCallback_;
1685
1686 info.capturerReadCallback = readCb_;
1687 }
1688
GetOffloadEnable()1689 bool CapturerInClientInner::GetOffloadEnable()
1690 {
1691 AUDIO_WARNING_LOG("not supported in capturer");
1692 return false;
1693 }
1694
GetSpatializationEnabled()1695 bool CapturerInClientInner::GetSpatializationEnabled()
1696 {
1697 AUDIO_WARNING_LOG("not supported in capturer");
1698 return false;
1699 }
1700
GetHighResolutionEnabled()1701 bool CapturerInClientInner::GetHighResolutionEnabled()
1702 {
1703 AUDIO_WARNING_LOG("not supported in capturer");
1704 return false;
1705 }
1706
GetStreamClass()1707 IAudioStream::StreamClass CapturerInClientInner::GetStreamClass()
1708 {
1709 return PA_STREAM;
1710 }
1711
SetSilentModeAndMixWithOthers(bool on)1712 void CapturerInClientInner::SetSilentModeAndMixWithOthers(bool on)
1713 {
1714 AUDIO_WARNING_LOG("not supported in capturer");
1715 return;
1716 }
1717
GetSilentModeAndMixWithOthers()1718 bool CapturerInClientInner::GetSilentModeAndMixWithOthers()
1719 {
1720 AUDIO_WARNING_LOG("not supported in capturer");
1721 return false;
1722 }
1723
RestoreAudioStream(bool needStoreState)1724 bool CapturerInClientInner::RestoreAudioStream(bool needStoreState)
1725 {
1726 CHECK_AND_RETURN_RET_LOG(proxyObj_ != nullptr, false, "proxyObj_ is null");
1727 CHECK_AND_RETURN_RET_LOG(state_ != NEW && state_ != INVALID && state_ != RELEASED, true,
1728 "state_ is %{public}d, no need for restore", state_.load());
1729 bool result = false;
1730 State oldState = state_;
1731 state_ = NEW;
1732 SetStreamTrackerState(false);
1733
1734 int32_t ret = SetAudioStreamInfo(streamParams_, proxyObj_);
1735 if (ret != SUCCESS) {
1736 goto error;
1737 }
1738 #ifdef HAS_FEATURE_INNERCAPTURER
1739 // for inner-capturer
1740 if (capturerInfo_.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
1741 ret = UpdatePlaybackCaptureConfig(filterConfig_);
1742 if (ret != SUCCESS) {
1743 goto error;
1744 }
1745 }
1746 #endif
1747 switch (oldState) {
1748 case RUNNING:
1749 result = StartAudioStream();
1750 break;
1751 case PAUSED:
1752 result = StartAudioStream() && PauseAudioStream();
1753 break;
1754 case STOPPED:
1755 case STOPPING:
1756 result = StartAudioStream() && StopAudioStream();
1757 break;
1758 default:
1759 break;
1760 }
1761 if (!result) {
1762 goto error;
1763 }
1764 return result;
1765
1766 error:
1767 AUDIO_ERR_LOG("RestoreAudioStream failed");
1768 state_ = oldState;
1769 return false;
1770 }
1771
JoinCallbackLoop()1772 void CapturerInClientInner::JoinCallbackLoop()
1773 {
1774 AUDIO_INFO_LOG("Not Support");
1775 }
1776
SetDefaultOutputDevice(const DeviceType defaultOutputDevice,bool skipForce)1777 int32_t CapturerInClientInner::SetDefaultOutputDevice(const DeviceType defaultOutputDevice, bool skipForce)
1778 {
1779 (void)defaultOutputDevice;
1780 (void)skipForce;
1781 AUDIO_WARNING_LOG("not supported in capturer");
1782 return ERROR;
1783 }
1784
GetFastStatus()1785 FastStatus CapturerInClientInner::GetFastStatus()
1786 {
1787 return FASTSTATUS_NORMAL;
1788 }
1789
GetDefaultOutputDevice()1790 DeviceType CapturerInClientInner::GetDefaultOutputDevice()
1791 {
1792 AUDIO_WARNING_LOG("not supported in capturer");
1793 return DEVICE_TYPE_NONE;
1794 }
1795
1796 // diffrence from GetAudioPosition only when set speed
GetAudioTimestampInfo(Timestamp & timestamp,Timestamp::Timestampbase base)1797 int32_t CapturerInClientInner::GetAudioTimestampInfo(Timestamp ×tamp, Timestamp::Timestampbase base)
1798 {
1799 return GetAudioTime(timestamp, base) ? SUCCESS : ERROR;
1800 }
1801
SetSwitchingStatus(bool isSwitching)1802 void CapturerInClientInner::SetSwitchingStatus(bool isSwitching)
1803 {
1804 AUDIO_WARNING_LOG("not supported in capturer");
1805 }
1806
GetRestoreInfo(RestoreInfo & restoreInfo)1807 void CapturerInClientInner::GetRestoreInfo(RestoreInfo &restoreInfo)
1808 {
1809 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1810 clientBuffer_->GetRestoreInfo(restoreInfo);
1811 return;
1812 }
1813
SetRestoreInfo(RestoreInfo & restoreInfo)1814 void CapturerInClientInner::SetRestoreInfo(RestoreInfo &restoreInfo)
1815 {
1816 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1817 clientBuffer_->SetRestoreInfo(restoreInfo);
1818 return;
1819 }
1820
CheckRestoreStatus()1821 RestoreStatus CapturerInClientInner::CheckRestoreStatus()
1822 {
1823 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1824 return clientBuffer_->CheckRestoreStatus();
1825 }
1826
SetRestoreStatus(RestoreStatus restoreStatus)1827 RestoreStatus CapturerInClientInner::SetRestoreStatus(RestoreStatus restoreStatus)
1828 {
1829 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1830 return clientBuffer_->SetRestoreStatus(restoreStatus);
1831 }
1832
FetchDeviceForSplitStream()1833 void CapturerInClientInner::FetchDeviceForSplitStream()
1834 {
1835 AUDIO_INFO_LOG("Fetch input device for split stream %{public}u", sessionId_);
1836 if (audioStreamTracker_ && audioStreamTracker_.get()) {
1837 audioStreamTracker_->FetchInputDeviceForTrack(sessionId_, state_, clientPid_, capturerInfo_);
1838 } else {
1839 AUDIO_WARNING_LOG("Tracker is nullptr, fail to split stream %{public}u", sessionId_);
1840 }
1841 SetRestoreStatus(NO_NEED_FOR_RESTORE);
1842 }
1843
SetCallStartByUserTid(pid_t tid)1844 void CapturerInClientInner::SetCallStartByUserTid(pid_t tid)
1845 {
1846 AUDIO_WARNING_LOG("not supported in capturer");
1847 }
1848
SetCallbackLoopTid(int32_t tid)1849 void CapturerInClientInner::SetCallbackLoopTid(int32_t tid)
1850 {
1851 AUDIO_INFO_LOG("Callback loop tid: %{public}d", tid);
1852 callbackLoopTid_ = tid;
1853 callbackLoopTidCv_.notify_all();
1854 }
1855
GetCallbackLoopTid()1856 int32_t CapturerInClientInner::GetCallbackLoopTid()
1857 {
1858 std::unique_lock<std::mutex> waitLock(callbackLoopTidMutex_);
1859 bool stopWaiting = callbackLoopTidCv_.wait_for(waitLock, std::chrono::seconds(1), [this] {
1860 return callbackLoopTid_ != -1; // callbackLoopTid_ will change when got notified.
1861 });
1862
1863 if (!stopWaiting) {
1864 AUDIO_WARNING_LOG("Wait timeout");
1865 callbackLoopTid_ = 0; // set tid to prevent get operation from getting stuck
1866 }
1867 return callbackLoopTid_;
1868 }
1869
ResetCallbackLoopTid()1870 void CapturerInClientInner::ResetCallbackLoopTid()
1871 {
1872 AUDIO_INFO_LOG("to -1");
1873 callbackLoopTid_ = -1;
1874 }
1875
GetStopFlag() const1876 bool CapturerInClientInner::GetStopFlag() const
1877 {
1878 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "Client OHAudioBuffer is nullptr");
1879 return clientBuffer_->GetStopFlag();
1880 }
1881 } // namespace AudioStandard
1882 } // namespace OHOS
1883 #endif // FAST_AUDIO_STREAM_H
1884