1 /*
2  * Copyright (c) 2023-2024 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 "RendererInClientInner"
20 #endif
21 
22 #include "futex_tool.h"
23 #include "renderer_in_client.h"
24 #include "renderer_in_client_private.h"
25 
26 #include "audio_errors.h"
27 #include "audio_policy_manager.h"
28 #include "audio_manager_base.h"
29 #include "audio_renderer_log.h"
30 #include "audio_ring_cache.h"
31 #include "audio_channel_blend.h"
32 #include "audio_server_death_recipient.h"
33 #include "audio_stream_tracker.h"
34 #include "audio_system_manager.h"
35 #include "audio_utils.h"
36 #include "futex_tool.h"
37 #include "ipc_stream_listener_impl.h"
38 #include "ipc_stream_listener_stub.h"
39 #include "volume_ramp.h"
40 #include "callback_handler.h"
41 #include "audio_speed.h"
42 #include "audio_spatial_channel_converter.h"
43 #include "audio_policy_manager.h"
44 #include "audio_spatialization_manager.h"
45 #include "policy_handler.h"
46 #include "audio_log_utils.h"
47 
48 #include "media_monitor_manager.h"
49 using namespace OHOS::HiviewDFX;
50 using namespace OHOS::AppExecFwk;
51 
52 namespace OHOS {
53 namespace AudioStandard {
54 namespace {
55 const uint64_t OLD_BUF_DURATION_IN_USEC = 92880; // This value is used for compatibility purposes.
56 const uint64_t MAX_BUF_DURATION_IN_USEC = 2000000; // 2S
57 const uint64_t AUDIO_FIRST_FRAME_LATENCY = 120; //ms
58 static const size_t MAX_WRITE_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 OFFLOAD_OPERATION_TIMEOUT_IN_MS = 8000; // 8000ms for offload
62 static const int32_t WRITE_CACHE_TIMEOUT_IN_MS = 1500; // 1500ms
63 static const int32_t WRITE_BUFFER_TIMEOUT_IN_MS = 20; // ms
64 static const int32_t SHORT_TIMEOUT_IN_MS = 20; // ms
65 static const uint32_t WAIT_FOR_NEXT_CB = 5000; // 5ms
66 static const int32_t HALF_FACTOR = 2;
67 static const int32_t DATA_CONNECTION_TIMEOUT_IN_MS = 1000; // ms
68 static constexpr int CB_QUEUE_CAPACITY = 3;
69 constexpr int32_t MAX_BUFFER_SIZE = 100000;
70 static constexpr int32_t ONE_MINUTE = 60;
71 static constexpr int32_t MEDIA_SERVICE_UID = 1013;
72 static const int32_t MAX_WRITE_INTERVAL_MS = 40;
73 } // namespace
74 
75 static AppExecFwk::BundleInfo gBundleInfo_;
76 
GetInstance(AudioStreamType eStreamType,int32_t appUid)77 std::shared_ptr<RendererInClient> RendererInClient::GetInstance(AudioStreamType eStreamType, int32_t appUid)
78 {
79     return std::make_shared<RendererInClientInner>(eStreamType, appUid);
80 }
81 
RendererInClientInner(AudioStreamType eStreamType,int32_t appUid)82 RendererInClientInner::RendererInClientInner(AudioStreamType eStreamType, int32_t appUid)
83     : eStreamType_(eStreamType), appUid_(appUid), cbBufferQueue_(CB_QUEUE_CAPACITY)
84 {
85     AUDIO_INFO_LOG("Create with StreamType:%{public}d appUid:%{public}d ", eStreamType_, appUid_);
86     audioStreamTracker_ = std::make_unique<AudioStreamTracker>(AUDIO_MODE_PLAYBACK, appUid);
87     state_ = NEW;
88 }
89 
~RendererInClientInner()90 RendererInClientInner::~RendererInClientInner()
91 {
92     AUDIO_INFO_LOG("~RendererInClientInner()");
93     DumpFileUtil::CloseDumpFile(&dumpOutFd_);
94     RendererInClientInner::ReleaseAudioStream(true);
95     std::lock_guard<std::mutex> runnerlock(runnerMutex_);
96     if (!runnerReleased_ && callbackHandler_ != nullptr) {
97         AUDIO_INFO_LOG("runner remove");
98         callbackHandler_->ReleaseEventRunner();
99         runnerReleased_ = true;
100         callbackHandler_ = nullptr;
101     }
102     UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
103     AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
104 }
105 
OnOperationHandled(Operation operation,int64_t result)106 int32_t RendererInClientInner::OnOperationHandled(Operation operation, int64_t result)
107 {
108     Trace trace(traceTag_ + " OnOperationHandled:" + std::to_string(operation));
109     AUDIO_INFO_LOG("sessionId %{public}d recv operation:%{public}d result:%{public}" PRId64".", sessionId_, operation,
110         result);
111     if (operation == SET_OFFLOAD_ENABLE) {
112         AUDIO_INFO_LOG("SET_OFFLOAD_ENABLE result:%{public}" PRId64".", result);
113         if (!offloadEnable_ && static_cast<bool>(result)) {
114             offloadStartReadPos_ = 0;
115         }
116         offloadEnable_ = static_cast<bool>(result);
117         rendererInfo_.pipeType = offloadEnable_ ? PIPE_TYPE_OFFLOAD : PIPE_TYPE_NORMAL_OUT;
118         return SUCCESS;
119     }
120 
121     if (operation == DATA_LINK_CONNECTING || operation == DATA_LINK_CONNECTED) {
122         if (operation == DATA_LINK_CONNECTING) {
123             isDataLinkConnected_ = false;
124         } else {
125             isDataLinkConnected_ = true;
126             dataConnectionCV_.notify_all();
127         }
128         return SUCCESS;
129     }
130 
131     std::unique_lock<std::mutex> lock(callServerMutex_);
132     notifiedOperation_ = operation;
133     notifiedResult_ = result;
134 
135     if (notifiedResult_ == SUCCESS) {
136         switch (operation) {
137             case START_STREAM :
138                 state_ = RUNNING;
139                 break;
140             case PAUSE_STREAM :
141                 state_ = PAUSED;
142                 break;
143             case STOP_STREAM :
144                 state_ = STOPPED;
145                 break;
146             default :
147                 break;
148         }
149     } else {
150         AUDIO_ERR_LOG("operation %{public}d failed, result: %{public}" PRId64 "", operation, result);
151     }
152 
153     callServerCV_.notify_all();
154     return SUCCESS;
155 }
156 
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId,uint64_t fullTokenId)157 void RendererInClientInner::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId, uint64_t fullTokenId)
158 {
159     AUDIO_INFO_LOG("PID:%{public}d UID:%{public}d.", clientPid, clientUid);
160     clientPid_ = clientPid;
161     clientUid_ = clientUid;
162     appTokenId_ = appTokenId;
163     fullTokenId_ = fullTokenId;
164 }
165 
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)166 int32_t RendererInClientInner::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
167 {
168     AUDIO_ERR_LOG("Unsupported operation!");
169     return ERR_NOT_SUPPORTED;
170 }
171 
SetRendererInfo(const AudioRendererInfo & rendererInfo)172 void RendererInClientInner::SetRendererInfo(const AudioRendererInfo &rendererInfo)
173 {
174     rendererInfo_ = rendererInfo;
175     if (rendererInfo_.streamUsage == STREAM_USAGE_SYSTEM ||
176         rendererInfo_.streamUsage == STREAM_USAGE_DTMF ||
177         rendererInfo_.streamUsage == STREAM_USAGE_ENFORCED_TONE ||
178         rendererInfo_.streamUsage == STREAM_USAGE_ULTRASONIC ||
179         rendererInfo_.streamUsage == STREAM_USAGE_NAVIGATION ||
180         rendererInfo_.streamUsage == STREAM_USAGE_NOTIFICATION) {
181         effectMode_ = EFFECT_NONE;
182     }
183     rendererInfo_.sceneType = GetEffectSceneName(rendererInfo_.streamUsage);
184     AUDIO_PRERELEASE_LOGI("SetRendererInfo with flag %{public}d, sceneType %{public}s", rendererInfo_.rendererFlags,
185         rendererInfo_.sceneType.c_str());
186     AudioSpatializationState spatializationState =
187         AudioPolicyManager::GetInstance().GetSpatializationState(rendererInfo_.streamUsage);
188     rendererInfo_.spatializationEnabled = spatializationState.spatializationEnabled;
189     rendererInfo_.headTrackingEnabled = spatializationState.headTrackingEnabled;
190     rendererInfo_.encodingType = curStreamParams_.encoding;
191     rendererInfo_.channelLayout = curStreamParams_.channelLayout;
192     UpdateTracker("UPDATE");
193 }
194 
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)195 void RendererInClientInner::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
196 {
197     AUDIO_WARNING_LOG("SetCapturerInfo is not supported");
198     return;
199 }
200 
RegisterTracker(const std::shared_ptr<AudioClientTracker> & proxyObj)201 void RendererInClientInner::RegisterTracker(const std::shared_ptr<AudioClientTracker> &proxyObj)
202 {
203     if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) {
204         // make sure sessionId_ is valid.
205         AUDIO_INFO_LOG("Calling register tracker, sessionid is %{public}d", sessionId_);
206         AudioRegisterTrackerInfo registerTrackerInfo;
207 
208         rendererInfo_.samplingRate = static_cast<AudioSamplingRate>(curStreamParams_.samplingRate);
209         rendererInfo_.format = static_cast<AudioSampleFormat>(curStreamParams_.format);
210         registerTrackerInfo.sessionId = sessionId_;
211         registerTrackerInfo.clientPid = clientPid_;
212         registerTrackerInfo.state = state_;
213         registerTrackerInfo.rendererInfo = rendererInfo_;
214         registerTrackerInfo.capturerInfo = capturerInfo_;
215         registerTrackerInfo.channelCount = curStreamParams_.channels;
216 
217         audioStreamTracker_->RegisterTracker(registerTrackerInfo, proxyObj);
218         streamTrackerRegistered_ = true;
219     }
220 }
221 
UpdateTracker(const std::string & updateCase)222 void RendererInClientInner::UpdateTracker(const std::string &updateCase)
223 {
224     if (audioStreamTracker_ && audioStreamTracker_.get()) {
225         AUDIO_DEBUG_LOG("Renderer:Calling Update tracker for %{public}s", updateCase.c_str());
226         audioStreamTracker_->UpdateTracker(sessionId_, state_, clientPid_, rendererInfo_, capturerInfo_);
227     }
228 }
229 
IsHightResolution() const230 bool RendererInClientInner::IsHightResolution() const noexcept
231 {
232     return eStreamType_ == STREAM_MUSIC && curStreamParams_.samplingRate >= SAMPLE_RATE_48000 &&
233            curStreamParams_.format >= SAMPLE_S24LE;
234 }
235 
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj)236 int32_t RendererInClientInner::SetAudioStreamInfo(const AudioStreamParams info,
237     const std::shared_ptr<AudioClientTracker> &proxyObj)
238 {
239     // In plan: If paramsIsSet_ is true, and new info is same as old info, return
240     AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
241         " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format,
242         eStreamType_, info.encoding);
243 
244     AudioXCollie guard("RendererInClientInner::SetAudioStreamInfo", CREATE_TIMEOUT_IN_SECOND);
245     if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
246         AUDIO_ERR_LOG("Unsupported audio parameter");
247         return ERR_NOT_SUPPORTED;
248     }
249 
250     streamParams_ = curStreamParams_ = info; // keep it for later use
251     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
252         ConverterConfig cfg = AudioPolicyManager::GetInstance().GetConverterConfig();
253         converter_ = std::make_unique<AudioSpatialChannelConverter>();
254         if (converter_ == nullptr || !converter_->Init(curStreamParams_, cfg) || !converter_->AllocateMem()) {
255             AUDIO_ERR_LOG("AudioStream: converter construct error");
256             return ERR_NOT_SUPPORTED;
257         }
258         converter_->ConverterChannels(curStreamParams_.channels, curStreamParams_.channelLayout);
259     }
260 
261     if (!IsPlaybackChannelRelatedInfoValid(curStreamParams_.channels, curStreamParams_.channelLayout)) {
262         return ERR_NOT_SUPPORTED;
263     }
264 
265     CHECK_AND_RETURN_RET_LOG(IAudioStream::GetByteSizePerFrame(curStreamParams_, sizePerFrameInByte_) == SUCCESS,
266         ERROR_INVALID_PARAM, "GetByteSizePerFrame failed with invalid params");
267 
268     if (state_ != NEW) {
269         AUDIO_ERR_LOG("State is not new, release existing stream and recreate, state %{public}d", state_.load());
270         int32_t ret = DeinitIpcStream();
271         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "release existing stream failed.");
272     }
273     paramsIsSet_ = true;
274     int32_t initRet = InitIpcStream();
275     CHECK_AND_RETURN_RET_LOG(initRet == SUCCESS, initRet, "Init stream failed: %{public}d", initRet);
276     state_ = PREPARED;
277 
278     // eg: 100005_44100_2_1_client_out.pcm
279     dumpOutFile_ = std::to_string(sessionId_) + "_" + std::to_string(curStreamParams_.samplingRate) + "_" +
280         std::to_string(curStreamParams_.channels) + "_" + std::to_string(curStreamParams_.format) + "_client_out.pcm";
281 
282     DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpOutFile_, &dumpOutFd_);
283     logUtilsTag_ = "[" + std::to_string(sessionId_) + "]NormalRenderer";
284     InitDirectPipeType();
285 
286     proxyObj_ = proxyObj;
287     RegisterTracker(proxyObj);
288     RegisterSpatializationStateEventListener();
289     return SUCCESS;
290 }
291 
InitDirectPipeType()292 void RendererInClientInner::InitDirectPipeType()
293 {
294     if (rendererInfo_.rendererFlags == AUDIO_FLAG_VOIP_DIRECT || IsHightResolution()) {
295         AudioPipeType originType = rendererInfo_.pipeType;
296         int32_t type = ipcStream_->GetStreamManagerType();
297         if (type == AUDIO_DIRECT_MANAGER_TYPE) {
298             rendererInfo_.pipeType = (rendererInfo_.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) ?
299                 PIPE_TYPE_CALL_OUT : PIPE_TYPE_DIRECT_MUSIC;
300         } else if (originType == PIPE_TYPE_DIRECT_MUSIC) {
301             rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
302         }
303     }
304 }
305 
306 std::mutex g_serverProxyMutex;
307 sptr<IStandardAudioService> gServerProxy_ = nullptr;
GetAudioServerProxy()308 const sptr<IStandardAudioService> RendererInClientInner::GetAudioServerProxy()
309 {
310     std::lock_guard<std::mutex> lock(g_serverProxyMutex);
311     if (gServerProxy_ == nullptr) {
312         auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
313         if (samgr == nullptr) {
314             AUDIO_ERR_LOG("GetAudioServerProxy: get sa manager failed");
315             return nullptr;
316         }
317         sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
318         if (object == nullptr) {
319             AUDIO_ERR_LOG("GetAudioServerProxy: get audio service remote object failed");
320             return nullptr;
321         }
322         gServerProxy_ = iface_cast<IStandardAudioService>(object);
323         if (gServerProxy_ == nullptr) {
324             AUDIO_ERR_LOG("GetAudioServerProxy: get audio service proxy failed");
325             return nullptr;
326         }
327 
328         // register death recipent to restore proxy
329         sptr<AudioServerDeathRecipient> asDeathRecipient = new(std::nothrow) AudioServerDeathRecipient(getpid());
330         if (asDeathRecipient != nullptr) {
331             asDeathRecipient->SetNotifyCb([] (pid_t pid) { AudioServerDied(pid); });
332             bool result = object->AddDeathRecipient(asDeathRecipient);
333             if (!result) {
334                 AUDIO_ERR_LOG("GetAudioServerProxy: failed to add deathRecipient");
335             }
336         }
337     }
338     sptr<IStandardAudioService> gasp = gServerProxy_;
339     return gasp;
340 }
341 
AudioServerDied(pid_t pid)342 void RendererInClientInner::AudioServerDied(pid_t pid)
343 {
344     AUDIO_INFO_LOG("audio server died clear proxy, will restore proxy in next call");
345     std::lock_guard<std::mutex> lock(g_serverProxyMutex);
346     gServerProxy_ = nullptr;
347 }
348 
OnHandle(uint32_t code,int64_t data)349 void RendererInClientInner::OnHandle(uint32_t code, int64_t data)
350 {
351     AUDIO_DEBUG_LOG("On handle event, event code: %{public}d, data: %{public}" PRIu64 "", code, data);
352     switch (code) {
353         case STATE_CHANGE_EVENT:
354             HandleStateChangeEvent(data);
355             break;
356         case RENDERER_MARK_REACHED_EVENT:
357             HandleRenderMarkReachedEvent(data);
358             break;
359         case RENDERER_PERIOD_REACHED_EVENT:
360             HandleRenderPeriodReachedEvent(data);
361             break;
362         default:
363             break;
364     }
365 }
366 
HandleStateChangeEvent(int64_t data)367 void RendererInClientInner::HandleStateChangeEvent(int64_t data)
368 {
369     State state = INVALID;
370     StateChangeCmdType cmdType = CMD_FROM_CLIENT;
371     ParamsToStateCmdType(data, state, cmdType);
372     std::unique_lock<std::mutex> lock(streamCbMutex_);
373     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
374     if (streamCb != nullptr) {
375         state = state != STOPPING ? state : STOPPED; // client only need STOPPED
376         streamCb->OnStateChange(state, cmdType);
377     }
378 }
379 
HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)380 void RendererInClientInner::HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)
381 {
382     AUDIO_DEBUG_LOG("Start HandleRenderMarkReachedEvent");
383     std::unique_lock<std::mutex> lock(markReachMutex_);
384     if (rendererPositionCallback_) {
385         rendererPositionCallback_->OnMarkReached(rendererMarkPosition);
386     }
387 }
388 
HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)389 void RendererInClientInner::HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)
390 {
391     AUDIO_DEBUG_LOG("Start HandleRenderPeriodReachedEvent");
392     std::unique_lock<std::mutex> lock(periodReachMutex_);
393     if (rendererPeriodPositionCallback_) {
394         rendererPeriodPositionCallback_->OnPeriodReached(rendererPeriodNumber);
395     }
396 }
397 
SafeSendCallbackEvent(uint32_t eventCode,int64_t data)398 void RendererInClientInner::SafeSendCallbackEvent(uint32_t eventCode, int64_t data)
399 {
400     std::lock_guard<std::mutex> lock(runnerMutex_);
401     AUDIO_INFO_LOG("Send callback event, code: %{public}u, data: %{public}" PRId64 "", eventCode, data);
402     CHECK_AND_RETURN_LOG(callbackHandler_ != nullptr && runnerReleased_ == false, "Runner is Released");
403     callbackHandler_->SendCallbackEvent(eventCode, data);
404 }
405 
InitCallbackHandler()406 void RendererInClientInner::InitCallbackHandler()
407 {
408     std::lock_guard<std::mutex> lock(runnerMutex_);
409     if (callbackHandler_ == nullptr) {
410         callbackHandler_ = CallbackHandler::GetInstance(shared_from_this(), "OS_AudioStateCB");
411     }
412 }
413 
414 // call this without lock, we should be able to call deinit in any case.
DeinitIpcStream()415 int32_t RendererInClientInner::DeinitIpcStream()
416 {
417     Trace trace("RendererInClientInner::DeinitIpcStream");
418     ipcStream_->Release();
419     ringCache_->ResetBuffer();
420     return SUCCESS;
421 }
422 
ConstructConfig()423 const AudioProcessConfig RendererInClientInner::ConstructConfig()
424 {
425     AudioProcessConfig config = {};
426 
427     config.appInfo.appPid = clientPid_;
428     config.appInfo.appUid = clientUid_;
429     config.appInfo.appTokenId = appTokenId_;
430     config.appInfo.appFullTokenId = fullTokenId_;
431 
432     config.streamInfo.channels = static_cast<AudioChannel>(curStreamParams_.channels);
433     config.streamInfo.encoding = static_cast<AudioEncodingType>(curStreamParams_.encoding);
434     config.streamInfo.format = static_cast<AudioSampleFormat>(curStreamParams_.format);
435     config.streamInfo.samplingRate = static_cast<AudioSamplingRate>(curStreamParams_.samplingRate);
436     config.streamInfo.channelLayout = static_cast<AudioChannelLayout>(curStreamParams_.channelLayout);
437     config.originalSessionId = curStreamParams_.originalSessionId;
438 
439     config.audioMode = AUDIO_MODE_PLAYBACK;
440 
441     if (rendererInfo_.rendererFlags != AUDIO_FLAG_NORMAL && rendererInfo_.rendererFlags != AUDIO_FLAG_VOIP_DIRECT) {
442         AUDIO_WARNING_LOG("ConstructConfig find renderer flag invalid:%{public}d", rendererInfo_.rendererFlags);
443         rendererInfo_.rendererFlags = 0;
444     }
445     config.rendererInfo = rendererInfo_;
446 
447     config.capturerInfo = {};
448 
449     config.streamType = eStreamType_;
450 
451     config.deviceType = AudioPolicyManager::GetInstance().GetActiveOutputDevice();
452 
453     config.privacyType = privacyType_;
454 
455     clientConfig_ = config;
456 
457     return config;
458 }
459 
InitSharedBuffer()460 int32_t RendererInClientInner::InitSharedBuffer()
461 {
462     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "InitSharedBuffer failed, null ipcStream_.");
463     int32_t ret = ipcStream_->ResolveBuffer(clientBuffer_);
464 
465     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && clientBuffer_ != nullptr, ret, "ResolveBuffer failed:%{public}d", ret);
466 
467     uint32_t totalSizeInFrame = 0;
468     uint32_t byteSizePerFrame = 0;
469     ret = clientBuffer_->GetSizeParameter(totalSizeInFrame, spanSizeInFrame_, byteSizePerFrame);
470 
471     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && byteSizePerFrame == sizePerFrameInByte_, ret, "GetSizeParameter failed"
472         ":%{public}d, byteSizePerFrame:%{public}u, sizePerFrameInByte_:%{public}zu", ret, byteSizePerFrame,
473         sizePerFrameInByte_);
474 
475     clientSpanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame;
476 
477     AUDIO_INFO_LOG("totalSizeInFrame_[%{public}u] spanSizeInFrame[%{public}u] sizePerFrameInByte_[%{public}zu]"
478         "clientSpanSizeInByte_[%{public}zu]", totalSizeInFrame, spanSizeInFrame_, sizePerFrameInByte_,
479         clientSpanSizeInByte_);
480 
481     return SUCCESS;
482 }
483 
484 // InitCacheBuffer should be able to modify the cache size between clientSpanSizeInByte_ and 4 * clientSpanSizeInByte_
InitCacheBuffer(size_t targetSize)485 int32_t RendererInClientInner::InitCacheBuffer(size_t targetSize)
486 {
487     CHECK_AND_RETURN_RET_LOG(clientSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "clientSpanSizeInByte_ invalid");
488 
489     AUDIO_INFO_LOG("old size:%{public}zu, new size:%{public}zu", cacheSizeInByte_, targetSize);
490     cacheSizeInByte_ = targetSize;
491 
492     if (ringCache_ == nullptr) {
493         ringCache_ = AudioRingCache::Create(cacheSizeInByte_);
494     } else {
495         OptResult result = ringCache_->ReConfig(cacheSizeInByte_, false); // false --> clear buffer
496         if (result.ret != OPERATION_SUCCESS) {
497             AUDIO_ERR_LOG("ReConfig AudioRingCache to size %{public}u failed:ret%{public}zu", result.ret, targetSize);
498             return ERR_OPERATION_FAILED;
499         }
500     }
501 
502     return SUCCESS;
503 }
504 
InitIpcStream()505 int32_t RendererInClientInner::InitIpcStream()
506 {
507     Trace trace("RendererInClientInner::InitIpcStream");
508     AudioProcessConfig config = ConstructConfig();
509     bool resetSilentMode = (gServerProxy_ == nullptr) ? true : false;
510     sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
511     CHECK_AND_RETURN_RET_LOG(gasp != nullptr, ERR_OPERATION_FAILED, "Create failed, can not get service.");
512     int32_t errorCode = 0;
513     sptr<IRemoteObject> ipcProxy = gasp->CreateAudioProcess(config, errorCode);
514     CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, ERR_OPERATION_FAILED, "failed with null ipcProxy.");
515     ipcStream_ = iface_cast<IpcStream>(ipcProxy);
516     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "failed when iface_cast.");
517 
518     // in plan next: old listener_ is destoried here, will server receive dieth notify?
519     listener_ = sptr<IpcStreamListenerImpl>::MakeSptr(shared_from_this());
520     int32_t ret = ipcStream_->RegisterStreamListener(listener_->AsObject());
521     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RegisterStreamListener failed:%{public}d", ret);
522 
523     if (resetSilentMode && gServerProxy_ != nullptr && silentModeAndMixWithOthers_) {
524         ipcStream_->SetSilentModeAndMixWithOthers(silentModeAndMixWithOthers_);
525     }
526 
527     ret = InitSharedBuffer();
528     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitSharedBuffer failed:%{public}d", ret);
529 
530     ret = InitCacheBuffer(clientSpanSizeInByte_);
531     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitCacheBuffer failed:%{public}d", ret);
532 
533     ret = ipcStream_->GetAudioSessionID(sessionId_);
534     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetAudioSessionID failed:%{public}d", ret);
535     traceTag_ = "[" + std::to_string(sessionId_) + "]RendererInClient"; // [100001]RendererInClient
536     InitCallbackHandler();
537     return SUCCESS;
538 }
539 
GetAudioStreamInfo(AudioStreamParams & info)540 int32_t RendererInClientInner::GetAudioStreamInfo(AudioStreamParams &info)
541 {
542     CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, ERR_OPERATION_FAILED, "Params is not set");
543     info = streamParams_;
544     return SUCCESS;
545 }
546 
CheckRecordingCreate(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,SourceType sourceType)547 bool RendererInClientInner::CheckRecordingCreate(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
548     SourceType sourceType)
549 {
550     AUDIO_WARNING_LOG("CheckRecordingCreate is not supported");
551     return false;
552 }
553 
CheckRecordingStateChange(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,AudioPermissionState state)554 bool RendererInClientInner::CheckRecordingStateChange(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
555     AudioPermissionState state)
556 {
557     AUDIO_WARNING_LOG("CheckRecordingCreate is not supported");
558     return false;
559 }
560 
GetAudioSessionID(uint32_t & sessionID)561 int32_t RendererInClientInner::GetAudioSessionID(uint32_t &sessionID)
562 {
563     CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != NEW), ERR_ILLEGAL_STATE,
564         "State error %{public}d", state_.load());
565     sessionID = sessionId_;
566     return SUCCESS;
567 }
568 
GetAudioPipeType(AudioPipeType & pipeType)569 void RendererInClientInner::GetAudioPipeType(AudioPipeType &pipeType)
570 {
571     pipeType = rendererInfo_.pipeType;
572 }
573 
GetState()574 State RendererInClientInner::GetState()
575 {
576     return state_;
577 }
578 
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)579 bool RendererInClientInner::GetAudioTime(Timestamp &timestamp, Timestamp::Timestampbase base)
580 {
581     CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
582     CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
583 
584     uint64_t readPos = 0;
585     int64_t handleTime = 0;
586     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
587     clientBuffer_->GetHandleInfo(readPos, handleTime);
588     if (readPos == 0 || handleTime == 0) {
589         AUDIO_WARNING_LOG("GetHandleInfo may failed");
590     }
591 
592     timestamp.framePosition = readPos;
593     int64_t audioTimeResult = handleTime;
594 
595     if (offloadEnable_) {
596         uint64_t timestampHdi = 0;
597         uint64_t paWriteIndex = 0;
598         uint64_t cacheTimeDsp = 0;
599         uint64_t cacheTimePa = 0;
600         ipcStream_->GetOffloadApproximatelyCacheTime(timestampHdi, paWriteIndex, cacheTimeDsp, cacheTimePa);
601         int64_t cacheTime = static_cast<int64_t>(cacheTimeDsp + cacheTimePa) * AUDIO_NS_PER_US;
602         int64_t timeNow = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
603             std::chrono::system_clock::now().time_since_epoch()).count());
604         int64_t deltaTimeStamp = (static_cast<int64_t>(timeNow) - static_cast<int64_t>(timestampHdi)) * AUDIO_NS_PER_US;
605         uint64_t paWriteIndexNs = paWriteIndex * AUDIO_NS_PER_US;
606         uint64_t readPosNs = readPos * AUDIO_MS_PER_SECOND / streamParams_.samplingRate * AUDIO_US_PER_S;
607 
608         int64_t deltaPaWriteIndexNs = static_cast<int64_t>(readPosNs) - static_cast<int64_t>(paWriteIndexNs);
609         int64_t cacheTimeNow = cacheTime - deltaTimeStamp + deltaPaWriteIndexNs;
610         if (offloadStartReadPos_ == 0) {
611             offloadStartReadPos_ = readPosNs;
612             offloadStartHandleTime_ = handleTime;
613         }
614         int64_t offloadDelta = 0;
615         if (offloadStartReadPos_ != 0) {
616             offloadDelta = (static_cast<int64_t>(readPosNs) - static_cast<int64_t>(offloadStartReadPos_)) -
617                            (handleTime - offloadStartHandleTime_) - cacheTimeNow;
618         }
619         audioTimeResult += offloadDelta;
620     }
621 
622     timestamp.time.tv_sec = static_cast<time_t>(audioTimeResult / AUDIO_NS_PER_SECOND);
623     timestamp.time.tv_nsec = static_cast<time_t>(audioTimeResult % AUDIO_NS_PER_SECOND);
624     AUDIO_DEBUG_LOG("audioTimeResult: %{public}" PRIi64, audioTimeResult);
625     return true;
626 }
627 
GetAudioPosition(Timestamp & timestamp,Timestamp::Timestampbase base)628 bool RendererInClientInner::GetAudioPosition(Timestamp &timestamp, Timestamp::Timestampbase base)
629 {
630     CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Renderer stream state is not RUNNING");
631     uint64_t readIndex = 0;
632     uint64_t timestampVal = 0;
633     uint64_t latency = 0;
634     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
635     int32_t ret = ipcStream_->GetAudioPosition(readIndex, timestampVal, latency);
636 
637     uint64_t framePosition = readIndex > lastFlushReadIndex_ ? readIndex - lastFlushReadIndex_ : 0;
638     framePosition = framePosition > latency ? framePosition - latency : 0;
639 
640     // add MCR latency
641     uint32_t mcrLatency = 0;
642     if (converter_ != nullptr) {
643         mcrLatency = converter_->GetLatency();
644         framePosition = framePosition - (mcrLatency * rendererRate_ / AUDIO_MS_PER_S);
645     }
646 
647     if (lastFramePosition_ < framePosition) {
648         lastFramePosition_ = framePosition;
649         lastFrameTimestamp_ = timestampVal;
650     } else {
651         AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
652         framePosition = lastFramePosition_;
653         timestampVal = lastFrameTimestamp_;
654     }
655     AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
656         ", timestamp %{public}" PRIu64 ", mcrLatency %{public}u, Sinklatency %{public}" PRIu64, framePosition,
657         lastFlushReadIndex_, timestampVal, mcrLatency, latency);
658 
659     timestamp.framePosition = framePosition;
660     timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
661     timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
662     return ret == SUCCESS;
663 }
664 
GetBufferSize(size_t & bufferSize)665 int32_t RendererInClientInner::GetBufferSize(size_t &bufferSize)
666 {
667     CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
668     bufferSize = clientSpanSizeInByte_;
669     if (renderMode_ == RENDER_MODE_CALLBACK) {
670         bufferSize = cbBufferSize_;
671     }
672 
673     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
674         CHECK_AND_RETURN_RET(converter_ != nullptr && converter_->GetInputBufferSize(bufferSize), ERR_OPERATION_FAILED);
675     }
676 
677     AUDIO_INFO_LOG("Buffer size is %{public}zu, mode is %{public}s", bufferSize, renderMode_ == RENDER_MODE_NORMAL ?
678         "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
679     return SUCCESS;
680 }
681 
GetFrameCount(uint32_t & frameCount)682 int32_t RendererInClientInner::GetFrameCount(uint32_t &frameCount)
683 {
684     CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
685     CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, ERR_ILLEGAL_STATE, "sizePerFrameInByte_ is 0!");
686     frameCount = spanSizeInFrame_;
687     if (renderMode_ == RENDER_MODE_CALLBACK) {
688         frameCount = cbBufferSize_ / sizePerFrameInByte_;
689         if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
690             frameCount = frameCount * curStreamParams_.channels / streamParams_.channels;
691         }
692     }
693     AUDIO_INFO_LOG("Frame count is %{public}u, mode is %{public}s", frameCount, renderMode_ == RENDER_MODE_NORMAL ?
694         "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
695     return SUCCESS;
696 }
697 
GetLatency(uint64_t & latency)698 int32_t RendererInClientInner::GetLatency(uint64_t &latency)
699 {
700     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
701     return ipcStream_->GetLatency(latency);
702 }
703 
SetAudioStreamType(AudioStreamType audioStreamType)704 int32_t RendererInClientInner::SetAudioStreamType(AudioStreamType audioStreamType)
705 {
706     AUDIO_ERR_LOG("Change stream type %{public}d to %{public}d is not supported", eStreamType_, audioStreamType);
707     return SUCCESS;
708 }
709 
SetInnerVolume(float volume)710 int32_t RendererInClientInner::SetInnerVolume(float volume)
711 {
712     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
713     clientBuffer_->SetStreamVolume(volume);
714     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
715     int32_t ret = ipcStream_->SetClientVolume();
716     if (ret != SUCCESS) {
717         AUDIO_ERR_LOG("Set Client Volume failed:%{public}u", ret);
718         return -1;
719     }
720     AUDIO_PRERELEASE_LOGI("SetClientVolume success, volume: %{public}f", volume);
721     return SUCCESS;
722 }
723 
SetVolume(float volume)724 int32_t RendererInClientInner::SetVolume(float volume)
725 {
726     Trace trace("RendererInClientInner::SetVolume:" + std::to_string(volume));
727     AUDIO_INFO_LOG("[%{public}s]sessionId:%{public}d volume:%{public}f", (offloadEnable_ ? "offload" : "normal"),
728         sessionId_, volume);
729     if (volume < 0.0 || volume > 1.0) {
730         AUDIO_ERR_LOG("SetVolume with invalid volume %{public}f", volume);
731         return ERR_INVALID_PARAM;
732     }
733     if (volumeRamp_.IsActive()) {
734         volumeRamp_.Terminate();
735     }
736     clientVolume_ = volume;
737 
738     return SetInnerVolume(volume);
739 }
740 
GetVolume()741 float RendererInClientInner::GetVolume()
742 {
743     Trace trace("RendererInClientInner::GetVolume:" + std::to_string(clientVolume_));
744     return clientVolume_;
745 }
746 
SetDuckVolume(float volume)747 int32_t RendererInClientInner::SetDuckVolume(float volume)
748 {
749     Trace trace("RendererInClientInner::SetDuckVolume:" + std::to_string(volume));
750     AUDIO_INFO_LOG("sessionId:%{public}d SetDuck:%{public}f", sessionId_, volume);
751     if (volume < 0.0 || volume > 1.0) {
752         AUDIO_ERR_LOG("SetDuckVolume with invalid volume %{public}f", volume);
753         return ERR_INVALID_PARAM;
754     }
755     duckVolume_ = volume;
756     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
757     clientBuffer_->SetDuckFactor(volume);
758     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
759     int32_t ret = ipcStream_->SetDuckFactor(volume);
760     if (ret != SUCCESS) {
761         AUDIO_ERR_LOG("Set Duck failed:%{public}u", ret);
762         return ERROR;
763     }
764     return SUCCESS;
765 }
766 
SetRenderRate(AudioRendererRate renderRate)767 int32_t RendererInClientInner::SetRenderRate(AudioRendererRate renderRate)
768 {
769     if (rendererRate_ == renderRate) {
770         AUDIO_INFO_LOG("Set same rate");
771         return SUCCESS;
772     }
773     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
774     rendererRate_ = renderRate;
775     return ipcStream_->SetRate(renderRate);
776 }
777 
SetSpeed(float speed)778 int32_t RendererInClientInner::SetSpeed(float speed)
779 {
780     if (audioSpeed_ == nullptr) {
781         audioSpeed_ = std::make_unique<AudioSpeed>(curStreamParams_.samplingRate, curStreamParams_.format,
782             curStreamParams_.channels);
783         GetBufferSize(bufferSize_);
784         speedBuffer_ = std::make_unique<uint8_t[]>(MAX_BUFFER_SIZE);
785     }
786     audioSpeed_->SetSpeed(speed);
787     speed_ = speed;
788     AUDIO_DEBUG_LOG("SetSpeed %{public}f, OffloadEnable %{public}d", speed_, offloadEnable_);
789     return SUCCESS;
790 }
791 
GetSpeed()792 float RendererInClientInner::GetSpeed()
793 {
794     return speed_;
795 }
796 
ChangeSpeed(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)797 int32_t RendererInClientInner::ChangeSpeed(uint8_t *buffer, int32_t bufferSize, std::unique_ptr<uint8_t []> &outBuffer,
798     int32_t &outBufferSize)
799 {
800     return audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, outBuffer, outBufferSize);
801 }
802 
GetRenderRate()803 AudioRendererRate RendererInClientInner::GetRenderRate()
804 {
805     AUDIO_INFO_LOG("Get RenderRate %{public}d", rendererRate_);
806     return rendererRate_;
807 }
808 
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)809 int32_t RendererInClientInner::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
810 {
811     if (callback == nullptr) {
812         AUDIO_ERR_LOG("SetStreamCallback failed. callback == nullptr");
813         return ERR_INVALID_PARAM;
814     }
815 
816     std::unique_lock<std::mutex> lock(streamCbMutex_);
817     streamCallback_ = callback;
818     lock.unlock();
819 
820     if (state_ != PREPARED) {
821         return SUCCESS;
822     }
823     SafeSendCallbackEvent(STATE_CHANGE_EVENT, PREPARED);
824     return SUCCESS;
825 }
826 
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)827 int32_t RendererInClientInner::SetRendererFirstFrameWritingCallback(
828     const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
829 {
830     AUDIO_INFO_LOG("SetRendererFirstFrameWritingCallback in.");
831     CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "callback is nullptr");
832     firstFrameWritingCb_ = callback;
833     return SUCCESS;
834 }
835 
OnFirstFrameWriting()836 void RendererInClientInner::OnFirstFrameWriting()
837 {
838     hasFirstFrameWrited_ = true;
839     CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null.");
840     uint64_t latency = AUDIO_FIRST_FRAME_LATENCY;
841     AUDIO_DEBUG_LOG("OnFirstFrameWriting: latency %{public}" PRIu64 "", latency);
842     firstFrameWritingCb_->OnFirstFrameWriting(latency);
843 }
844 
InitCallbackBuffer(uint64_t bufferDurationInUs)845 void RendererInClientInner::InitCallbackBuffer(uint64_t bufferDurationInUs)
846 {
847     if (bufferDurationInUs > MAX_BUF_DURATION_IN_USEC) {
848         AUDIO_ERR_LOG("InitCallbackBuffer with invalid duration %{public}" PRIu64", use default instead.",
849             bufferDurationInUs);
850         bufferDurationInUs = OLD_BUF_DURATION_IN_USEC;
851     }
852     // Calculate buffer size based on duration.
853 
854     size_t metaSize = 0;
855     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
856         CHECK_AND_RETURN_LOG(converter_ != nullptr, "converter is not inited");
857         metaSize = converter_->GetMetaSize();
858         converter_->GetInputBufferSize(cbBufferSize_);
859     } else {
860         cbBufferSize_ = static_cast<size_t>(bufferDurationInUs * curStreamParams_.samplingRate / AUDIO_US_PER_S) *
861             sizePerFrameInByte_;
862     }
863     AUDIO_INFO_LOG("duration %{public}" PRIu64 ", ecodingType: %{public}d, size: %{public}zu, metaSize: %{public}zu",
864         bufferDurationInUs, curStreamParams_.encoding, cbBufferSize_, metaSize);
865     std::lock_guard<std::mutex> lock(cbBufferMutex_);
866     cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_ + metaSize);
867 }
868 
SetRenderMode(AudioRenderMode renderMode)869 int32_t RendererInClientInner::SetRenderMode(AudioRenderMode renderMode)
870 {
871     AUDIO_INFO_LOG("SetRenderMode to %{public}s", renderMode == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
872         "RENDER_MODE_CALLBACK");
873     if (renderMode_ == renderMode) {
874         return SUCCESS;
875     }
876 
877     // renderMode_ is inited as RENDER_MODE_NORMAL, can only be set to RENDER_MODE_CALLBACK.
878     if (renderMode_ == RENDER_MODE_CALLBACK && renderMode == RENDER_MODE_NORMAL) {
879         AUDIO_ERR_LOG("SetRenderMode from callback to normal is not supported.");
880         return ERR_INCORRECT_MODE;
881     }
882 
883     // state check
884     if (state_ != PREPARED && state_ != NEW) {
885         AUDIO_ERR_LOG("SetRenderMode failed. invalid state:%{public}d", state_.load());
886         return ERR_ILLEGAL_STATE;
887     }
888     renderMode_ = renderMode;
889 
890     // init callbackLoop_
891     callbackLoop_ = std::thread([this] { this->WriteCallbackFunc(); });
892     pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioWriteCB");
893 
894     std::unique_lock<std::mutex> threadStartlock(statusMutex_);
895     bool stopWaiting = cbThreadCv_.wait_for(threadStartlock, std::chrono::milliseconds(SHORT_TIMEOUT_IN_MS), [this] {
896         return cbThreadReleased_ == false; // When thread is started, cbThreadReleased_ will be false. So stop waiting.
897     });
898     if (!stopWaiting) {
899         AUDIO_WARNING_LOG("Init OS_AudioWriteCB thread time out");
900     }
901 
902     InitCallbackBuffer(OLD_BUF_DURATION_IN_USEC);
903     return SUCCESS;
904 }
905 
GetRenderMode()906 AudioRenderMode RendererInClientInner::GetRenderMode()
907 {
908     AUDIO_INFO_LOG("Render mode is %{public}s", renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
909         "RENDER_MODE_CALLBACK");
910     return renderMode_;
911 }
912 
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)913 int32_t RendererInClientInner::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
914 {
915     CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "Invalid null callback");
916     CHECK_AND_RETURN_RET_LOG(renderMode_ == RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE, "incorrect render mode");
917     std::lock_guard<std::mutex> lock(writeCbMutex_);
918     writeCb_ = callback;
919     return SUCCESS;
920 }
921 
922 // Sleep or wait in WaitForRunning to avoid dead looping.
WaitForRunning()923 bool RendererInClientInner::WaitForRunning()
924 {
925     Trace trace("RendererInClientInner::WaitForRunning");
926     // check renderer state_: call client write only in running else wait on statusMutex_
927     std::unique_lock<std::mutex> stateLock(statusMutex_);
928     if (state_ != RUNNING) {
929         bool stopWaiting = cbThreadCv_.wait_for(stateLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
930             return state_ == RUNNING || cbThreadReleased_;
931         });
932         if (cbThreadReleased_) {
933             AUDIO_INFO_LOG("CBThread end in non-running status, sessionID :%{public}d", sessionId_);
934             return false;
935         }
936         if (!stopWaiting) {
937             AUDIO_DEBUG_LOG("Wait timeout, current state_ is %{public}d", state_.load()); // wait 0.5s
938             return false;
939         }
940     }
941     return true;
942 }
943 
ProcessWriteInner(BufferDesc & bufferDesc)944 int32_t RendererInClientInner::ProcessWriteInner(BufferDesc &bufferDesc)
945 {
946     int32_t result = 0; // Ensure result with default value.
947     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
948         result = WriteInner(bufferDesc.buffer, bufferDesc.bufLength, bufferDesc.metaBuffer, bufferDesc.metaLength);
949     }
950     if (curStreamParams_.encoding == ENCODING_PCM) {
951         if (bufferDesc.dataLength != 0) {
952             result = WriteInner(bufferDesc.buffer, bufferDesc.bufLength);
953             sleepCount_ = LOG_COUNT_LIMIT;
954         } else {
955             if (sleepCount_++ == LOG_COUNT_LIMIT) {
956                 sleepCount_ = 0;
957                 AUDIO_WARNING_LOG("OnWriteData Process 1st or 500 times INVALID buffer");
958             }
959             usleep(WAIT_FOR_NEXT_CB);
960         }
961     }
962     if (result < 0) {
963         AUDIO_WARNING_LOG("Call write fail, result:%{public}d, bufLength:%{public}zu", result, bufferDesc.bufLength);
964     }
965     return result;
966 }
967 
WriteCallbackFunc()968 void RendererInClientInner::WriteCallbackFunc()
969 {
970     AUDIO_INFO_LOG("WriteCallbackFunc start, sessionID :%{public}d", sessionId_);
971     cbThreadReleased_ = false;
972 
973     // Modify thread priority is not need as first call write will do these work.
974     cbThreadCv_.notify_one();
975 
976     // start loop
977     while (!cbThreadReleased_) {
978         Trace traceLoop("RendererInClientInner::WriteCallbackFunc");
979         if (!WaitForRunning()) {
980             continue;
981         }
982         if (cbBufferQueue_.Size() > 1) { // One callback, one enqueue, queue size should always be 1.
983             AUDIO_WARNING_LOG("The queue is too long, reducing data through loops");
984         }
985         BufferDesc temp;
986         while (cbBufferQueue_.PopNotWait(temp)) {
987             Trace traceQueuePop("RendererInClientInner::QueueWaitPop");
988             if (state_ != RUNNING) {
989                 cbBufferQueue_.Push(temp);
990                 AUDIO_INFO_LOG("Repush left buffer in queue");
991                 break;
992             }
993             traceQueuePop.End();
994             // call write here.
995             int32_t result = ProcessWriteInner(temp);
996             // only run in pause scene
997             if (result > 0 && static_cast<size_t>(result) < temp.dataLength) {
998                 BufferDesc tmp = {temp.buffer + static_cast<size_t>(result),
999                     temp.bufLength - static_cast<size_t>(result), temp.dataLength - static_cast<size_t>(result)};
1000                 cbBufferQueue_.Push(tmp);
1001                 AUDIO_INFO_LOG("Repush %{public}zu bytes in queue", temp.dataLength - static_cast<size_t>(result));
1002                 break;
1003             }
1004         }
1005         if (state_ != RUNNING) { continue; }
1006         // call client write
1007         std::unique_lock<std::mutex> lockCb(writeCbMutex_);
1008         if (writeCb_ != nullptr) {
1009             Trace traceCb("RendererInClientInner::OnWriteData");
1010             writeCb_->OnWriteData(cbBufferSize_);
1011         }
1012         lockCb.unlock();
1013 
1014         Trace traceQueuePush("RendererInClientInner::QueueWaitPush");
1015         std::unique_lock<std::mutex> lockBuffer(cbBufferMutex_);
1016         cbBufferQueue_.WaitNotEmptyFor(std::chrono::milliseconds(WRITE_BUFFER_TIMEOUT_IN_MS));
1017     }
1018     AUDIO_INFO_LOG("CBThread end sessionID :%{public}d", sessionId_);
1019 }
1020 
SetCaptureMode(AudioCaptureMode captureMode)1021 int32_t RendererInClientInner::SetCaptureMode(AudioCaptureMode captureMode)
1022 {
1023     AUDIO_ERR_LOG("SetCaptureMode is not supported");
1024     return ERROR;
1025 }
1026 
GetCaptureMode()1027 AudioCaptureMode RendererInClientInner::GetCaptureMode()
1028 {
1029     AUDIO_ERR_LOG("GetCaptureMode is not supported");
1030     return CAPTURE_MODE_NORMAL; // not supported
1031 }
1032 
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)1033 int32_t RendererInClientInner::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
1034 {
1035     AUDIO_ERR_LOG("SetCapturerReadCallback is not supported");
1036     return ERROR;
1037 }
1038 
GetBufferDesc(BufferDesc & bufDesc)1039 int32_t RendererInClientInner::GetBufferDesc(BufferDesc &bufDesc)
1040 {
1041     Trace trace("RendererInClientInner::GetBufferDesc");
1042     if (renderMode_ != RENDER_MODE_CALLBACK) {
1043         AUDIO_ERR_LOG("GetBufferDesc is not supported. Render mode is not callback.");
1044         return ERR_INCORRECT_MODE;
1045     }
1046     std::lock_guard<std::mutex> lock(cbBufferMutex_);
1047     bufDesc.buffer = cbBuffer_.get();
1048     bufDesc.bufLength = cbBufferSize_;
1049     bufDesc.dataLength = cbBufferSize_;
1050     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
1051         CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_INVALID_OPERATION, "converter is not inited");
1052         bufDesc.metaBuffer = bufDesc.buffer + cbBufferSize_;
1053         bufDesc.metaLength = converter_->GetMetaSize();
1054     }
1055     return SUCCESS;
1056 }
1057 
GetBufQueueState(BufferQueueState & bufState)1058 int32_t RendererInClientInner::GetBufQueueState(BufferQueueState &bufState)
1059 {
1060     Trace trace("RendererInClientInner::GetBufQueueState");
1061     if (renderMode_ != RENDER_MODE_CALLBACK) {
1062         AUDIO_ERR_LOG("GetBufQueueState is not supported. Render mode is not callback.");
1063         return ERR_INCORRECT_MODE;
1064     }
1065     // only one buffer in queue.
1066     bufState.numBuffers = 1;
1067     bufState.currentIndex = 0;
1068     return SUCCESS;
1069 }
1070 
Enqueue(const BufferDesc & bufDesc)1071 int32_t RendererInClientInner::Enqueue(const BufferDesc &bufDesc)
1072 {
1073     Trace trace("RendererInClientInner::Enqueue " + std::to_string(bufDesc.bufLength));
1074     if (renderMode_ != RENDER_MODE_CALLBACK) {
1075         AUDIO_ERR_LOG("Enqueue is not supported. Render mode is not callback.");
1076         return ERR_INCORRECT_MODE;
1077     }
1078     CHECK_AND_RETURN_RET_LOG(bufDesc.buffer != nullptr && bufDesc.bufLength != 0, ERR_INVALID_PARAM, "Invalid buffer");
1079     CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID ||
1080             converter_ != nullptr && converter_->CheckInputValid(bufDesc),
1081         ERR_INVALID_PARAM, "Invalid buffer desc");
1082     if (bufDesc.bufLength > cbBufferSize_ || bufDesc.dataLength > cbBufferSize_) {
1083         AUDIO_WARNING_LOG("Invalid bufLength:%{public}zu or dataLength:%{public}zu, should be %{public}zu",
1084             bufDesc.bufLength, bufDesc.dataLength, cbBufferSize_);
1085     }
1086 
1087     BufferDesc temp = bufDesc;
1088 
1089     if (state_ == RELEASED) {
1090         AUDIO_WARNING_LOG("Invalid state: %{public}d", state_.load());
1091         return ERR_ILLEGAL_STATE;
1092     }
1093     // Call write here may block, so put it in loop callbackLoop_
1094     cbBufferQueue_.Push(temp);
1095     return SUCCESS;
1096 }
1097 
Clear()1098 int32_t RendererInClientInner::Clear()
1099 {
1100     Trace trace("RendererInClientInner::Clear");
1101     if (renderMode_ != RENDER_MODE_CALLBACK) {
1102         AUDIO_ERR_LOG("Clear is not supported. Render mode is not callback.");
1103         return ERR_INCORRECT_MODE;
1104     }
1105     std::unique_lock<std::mutex> lock(cbBufferMutex_);
1106     int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
1107     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
1108     lock.unlock();
1109     FlushAudioStream();
1110     return SUCCESS;
1111 }
1112 
SetLowPowerVolume(float volume)1113 int32_t RendererInClientInner::SetLowPowerVolume(float volume)
1114 {
1115     AUDIO_INFO_LOG("Volume number: %{public}f", volume);
1116     if (volume < 0.0 || volume > 1.0) {
1117         AUDIO_ERR_LOG("Invalid param: %{public}f", volume);
1118         return ERR_INVALID_PARAM;
1119     }
1120     lowPowerVolume_ = volume;
1121 
1122     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1123     return ipcStream_->SetLowPowerVolume(lowPowerVolume_);
1124 }
1125 
GetLowPowerVolume()1126 float RendererInClientInner::GetLowPowerVolume()
1127 {
1128     return lowPowerVolume_;
1129 }
1130 
SetOffloadMode(int32_t state,bool isAppBack)1131 int32_t RendererInClientInner::SetOffloadMode(int32_t state, bool isAppBack)
1132 {
1133     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1134     return ipcStream_->SetOffloadMode(state, isAppBack);
1135 }
1136 
UnsetOffloadMode()1137 int32_t RendererInClientInner::UnsetOffloadMode()
1138 {
1139     rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
1140     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1141     return ipcStream_->UnsetOffloadMode();
1142 }
1143 
GetSingleStreamVolume()1144 float RendererInClientInner::GetSingleStreamVolume()
1145 {
1146     // in plan. For now, keep it consistent with fast_audio_stream
1147     return 1.0f;
1148 }
1149 
GetAudioEffectMode()1150 AudioEffectMode RendererInClientInner::GetAudioEffectMode()
1151 {
1152     AUDIO_DEBUG_LOG("Current audio effect mode is %{public}d", effectMode_);
1153     return effectMode_;
1154 }
1155 
SetAudioEffectMode(AudioEffectMode effectMode)1156 int32_t RendererInClientInner::SetAudioEffectMode(AudioEffectMode effectMode)
1157 {
1158     if (effectMode_ == effectMode) {
1159         AUDIO_INFO_LOG("Set same effect mode");
1160         return SUCCESS;
1161     }
1162     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1163     int32_t ret = ipcStream_->SetAudioEffectMode(effectMode);
1164     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Set audio effect mode failed");
1165     effectMode_ = effectMode;
1166     return SUCCESS;
1167 }
1168 
GetFramesWritten()1169 int64_t RendererInClientInner::GetFramesWritten()
1170 {
1171     return totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1172 }
1173 
GetFramesRead()1174 int64_t RendererInClientInner::GetFramesRead()
1175 {
1176     AUDIO_ERR_LOG("not supported");
1177     return -1;
1178 }
1179 
1180 
SetInnerCapturerState(bool isInnerCapturer)1181 void RendererInClientInner::SetInnerCapturerState(bool isInnerCapturer)
1182 {
1183     AUDIO_ERR_LOG("SetInnerCapturerState is not supported");
1184     return;
1185 }
1186 
SetWakeupCapturerState(bool isWakeupCapturer)1187 void RendererInClientInner::SetWakeupCapturerState(bool isWakeupCapturer)
1188 {
1189     AUDIO_ERR_LOG("SetWakeupCapturerState is not supported");
1190     return;
1191 }
1192 
SetCapturerSource(int capturerSource)1193 void RendererInClientInner::SetCapturerSource(int capturerSource)
1194 {
1195     AUDIO_ERR_LOG("SetCapturerSource is not supported");
1196     return;
1197 }
1198 
SetPrivacyType(AudioPrivacyType privacyType)1199 void RendererInClientInner::SetPrivacyType(AudioPrivacyType privacyType)
1200 {
1201     if (privacyType_ == privacyType) {
1202         AUDIO_INFO_LOG("Set same privacy type");
1203         return;
1204     }
1205     privacyType_ = privacyType;
1206     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
1207     int32_t ret = ipcStream_->SetPrivacyType(privacyType);
1208     CHECK_AND_RETURN_LOG(ret == SUCCESS, "Set privacy type failed");
1209 }
1210 
StartAudioStream(StateChangeCmdType cmdType,AudioStreamDeviceChangeReasonExt reason)1211 bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType,
1212     AudioStreamDeviceChangeReasonExt reason)
1213 {
1214     Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_));
1215     std::unique_lock<std::mutex> statusLock(statusMutex_);
1216     if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) {
1217         AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load());
1218         return false;
1219     }
1220 
1221     hasFirstFrameWrited_ = false;
1222     if (audioStreamTracker_ && audioStreamTracker_.get()) {
1223         audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_, RUNNING, clientPid_, rendererInfo_, reason);
1224     }
1225     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1226     int32_t ret = ipcStream_->Start();
1227     if (ret != SUCCESS) {
1228         AUDIO_ERR_LOG("Start call server failed:%{public}u", ret);
1229         return false;
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 state_ == RUNNING; // will be false when got notified.
1234     });
1235     if (!stopWaiting) {
1236         AUDIO_ERR_LOG("Start failed: timeout");
1237         ipcStream_->Stop();
1238         return false;
1239     }
1240 
1241     waitLock.unlock();
1242 
1243     AUDIO_INFO_LOG("Start SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1244     UpdateTracker("RUNNING");
1245 
1246     std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
1247     if (!isDataLinkConnected_) {
1248         AUDIO_INFO_LOG("data-connection blocking starts.");
1249         stopWaiting = dataConnectionCV_.wait_for(
1250             dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
1251                 return isDataLinkConnected_;
1252             });
1253         AUDIO_INFO_LOG("data-connection blocking ends.");
1254     }
1255     dataConnectionWaitLock.unlock();
1256 
1257     offloadStartReadPos_ = 0;
1258     if (renderMode_ == RENDER_MODE_CALLBACK) {
1259         // start the callback-write thread
1260         cbThreadCv_.notify_all();
1261     }
1262     statusLock.unlock();
1263     // in plan: call HiSysEventWrite
1264     int64_t param = -1;
1265     StateCmdTypeToParams(param, state_, cmdType);
1266     SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1267     preWriteEndTime_ = 0;
1268     return true;
1269 }
1270 
PauseAudioStream(StateChangeCmdType cmdType)1271 bool RendererInClientInner::PauseAudioStream(StateChangeCmdType cmdType)
1272 {
1273     Trace trace("RendererInClientInner::PauseAudioStream " + std::to_string(sessionId_));
1274     std::unique_lock<std::mutex> statusLock(statusMutex_);
1275     if (state_ != RUNNING) {
1276         AUDIO_ERR_LOG("State is not RUNNING. Illegal state:%{public}u", state_.load());
1277         return false;
1278     }
1279 
1280     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1281     int32_t ret = ipcStream_->Pause();
1282     if (ret != SUCCESS) {
1283         AUDIO_ERR_LOG("call server failed:%{public}u", ret);
1284         return false;
1285     }
1286     std::unique_lock<std::mutex> waitLock(callServerMutex_);
1287     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1288         return state_ == PAUSED; // will be false when got notified.
1289     });
1290     if (!stopWaiting) {
1291         AUDIO_ERR_LOG("Pause failed: timeout");
1292         return false;
1293     }
1294 
1295     waitLock.unlock();
1296 
1297     FutexTool::FutexWake(clientBuffer_->GetFutex());
1298     statusLock.unlock();
1299 
1300     // in plan: call HiSysEventWrite
1301     int64_t param = -1;
1302     StateCmdTypeToParams(param, state_, cmdType);
1303     SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1304 
1305     AUDIO_INFO_LOG("Pause SUCCESS, sessionId %{public}d, uid %{public}d, mode %{public}s", sessionId_,
1306         clientUid_, renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
1307     UpdateTracker("PAUSED");
1308     return true;
1309 }
1310 
StopAudioStream()1311 bool RendererInClientInner::StopAudioStream()
1312 {
1313     Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_));
1314     AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1315     std::unique_lock<std::mutex> statusLock(statusMutex_);
1316     std::lock_guard<std::mutex> lock(writeMutex_);
1317     if (!offloadEnable_) {
1318         DrainAudioStreamInner(true);
1319     }
1320 
1321     if (state_ == STOPPED) {
1322         AUDIO_INFO_LOG("Renderer in client is already stopped");
1323         return true;
1324     }
1325     if ((state_ != RUNNING) && (state_ != PAUSED)) {
1326         AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load());
1327         return false;
1328     }
1329 
1330     std::unique_lock<std::mutex> waitLock(callServerMutex_);
1331     if (renderMode_ == RENDER_MODE_CALLBACK) {
1332         state_ = STOPPING;
1333         AUDIO_INFO_LOG("Stop begin in callback mode sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1334     }
1335 
1336     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1337     int32_t ret = ipcStream_->Stop();
1338     if (ret != SUCCESS) {
1339         AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret);
1340         return false;
1341     }
1342 
1343     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1344         return state_ == STOPPED; // will be false when got notified.
1345     });
1346     if (!stopWaiting) {
1347         AUDIO_ERR_LOG("Stop failed: timeout");
1348         state_ = INVALID;
1349         return false;
1350     }
1351 
1352     waitLock.unlock();
1353 
1354     FutexTool::FutexWake(clientBuffer_->GetFutex());
1355     statusLock.unlock();
1356 
1357     // in plan: call HiSysEventWrite
1358     SafeSendCallbackEvent(STATE_CHANGE_EVENT, state_);
1359 
1360     AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1361     UpdateTracker("STOPPED");
1362     return true;
1363 }
1364 
ReleaseAudioStream(bool releaseRunner,bool isSwitchStream)1365 bool RendererInClientInner::ReleaseAudioStream(bool releaseRunner, bool isSwitchStream)
1366 {
1367     (void)isSwitchStream;
1368     AUDIO_PRERELEASE_LOGI("Enter");
1369     std::unique_lock<std::mutex> statusLock(statusMutex_);
1370     if (state_ == RELEASED) {
1371         AUDIO_WARNING_LOG("Already released, do nothing");
1372         return true;
1373     }
1374     state_ = RELEASED;
1375     statusLock.unlock();
1376 
1377     Trace trace("RendererInClientInner::ReleaseAudioStream " + std::to_string(sessionId_));
1378     if (ipcStream_ != nullptr) {
1379         ipcStream_->Release();
1380     } else {
1381         AUDIO_WARNING_LOG("release while ipcStream is null");
1382     }
1383 
1384     // no lock, call release in any case, include blocked case.
1385     std::unique_lock<std::mutex> runnerlock(runnerMutex_);
1386     if (releaseRunner && callbackHandler_ != nullptr) {
1387         callbackHandler_->ReleaseEventRunner();
1388         runnerReleased_ = true;
1389         callbackHandler_ = nullptr;
1390     }
1391     runnerlock.unlock();
1392 
1393     // clear write callback
1394     if (renderMode_ == RENDER_MODE_CALLBACK) {
1395         cbThreadReleased_ = true; // stop loop
1396         cbThreadCv_.notify_all();
1397         FutexTool::FutexWake(clientBuffer_->GetFutex(), IS_PRE_EXIT);
1398         if (callbackLoop_.joinable()) {
1399             callbackLoop_.join();
1400         }
1401     }
1402     paramsIsSet_ = false;
1403 
1404     std::unique_lock<std::mutex> lock(streamCbMutex_);
1405     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1406     if (streamCb != nullptr) {
1407         AUDIO_INFO_LOG("Notify client the state is released");
1408         streamCb->OnStateChange(RELEASED, CMD_FROM_CLIENT);
1409     }
1410     lock.unlock();
1411 
1412     UpdateTracker("RELEASED");
1413     AUDIO_INFO_LOG("Release end, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1414 
1415     audioSpeed_.reset();
1416     audioSpeed_ = nullptr;
1417     return true;
1418 }
1419 
FlushAudioStream()1420 bool RendererInClientInner::FlushAudioStream()
1421 {
1422     Trace trace("RendererInClientInner::FlushAudioStream " + std::to_string(sessionId_));
1423     std::unique_lock<std::mutex> statusLock(statusMutex_);
1424     std::lock_guard<std::mutex>lock(writeMutex_);
1425     if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
1426         AUDIO_ERR_LOG("Flush failed. Illegal state:%{public}u", state_.load());
1427         return false;
1428     }
1429 
1430     // clear cbBufferQueue
1431     if (renderMode_ == RENDER_MODE_CALLBACK) {
1432         cbBufferQueue_.Clear();
1433         if (memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_) != EOK) {
1434             AUDIO_ERR_LOG("memset_s buffer failed");
1435         };
1436     }
1437 
1438     CHECK_AND_RETURN_RET_LOG(FlushRingCache() == SUCCESS, false, "Flush cache failed");
1439 
1440     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1441     int32_t ret = ipcStream_->Flush();
1442     if (ret != SUCCESS) {
1443         AUDIO_ERR_LOG("Flush call server failed:%{public}u", ret);
1444         return false;
1445     }
1446     std::unique_lock<std::mutex> waitLock(callServerMutex_);
1447     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1448         return notifiedOperation_ == FLUSH_STREAM; // will be false when got notified.
1449     });
1450 
1451     if (notifiedOperation_ != FLUSH_STREAM || notifiedResult_ != SUCCESS) {
1452         AUDIO_ERR_LOG("Flush failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1453             (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1454         notifiedOperation_ = MAX_OPERATION_CODE;
1455         return false;
1456     }
1457     notifiedOperation_ = MAX_OPERATION_CODE;
1458     waitLock.unlock();
1459     ResetFramePosition();
1460     AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
1461     return true;
1462 }
1463 
FlushRingCache()1464 int32_t RendererInClientInner::FlushRingCache()
1465 {
1466     ringCache_->ResetBuffer();
1467     return SUCCESS;
1468 }
1469 
DrainRingCache()1470 int32_t RendererInClientInner::DrainRingCache()
1471 {
1472     // send all data in ringCache_ to server even if GetReadableSize() < clientSpanSizeInByte_.
1473     Trace trace("RendererInClientInner::DrainRingCache " + std::to_string(sessionId_));
1474 
1475     OptResult result = ringCache_->GetReadableSize();
1476     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_OPERATION_FAILED, "ring cache unreadable");
1477     size_t readableSize = result.size;
1478     if (readableSize == 0) {
1479         AUDIO_WARNING_LOG("Readable size is already zero");
1480         return SUCCESS;
1481     }
1482 
1483     BufferDesc desc = {};
1484     uint64_t curWriteIndex = clientBuffer_->GetCurWriteFrame();
1485     int32_t ret = clientBuffer_->GetWriteBuffer(curWriteIndex, desc);
1486     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "GetWriteBuffer failed %{public}d", ret);
1487 
1488     // if readableSize < clientSpanSizeInByte_, server will recv a data with some empty data.
1489     // it looks like this: |*******_____|
1490     size_t minSize = std::min(readableSize, clientSpanSizeInByte_);
1491     result = ringCache_->Dequeue({desc.buffer, minSize});
1492     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "ringCache Dequeue failed %{public}d", result.ret);
1493     clientBuffer_->SetCurWriteFrame(curWriteIndex + spanSizeInFrame_);
1494     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is nullptr");
1495     ipcStream_->UpdatePosition(); // notiify server update position
1496     HandleRendererPositionChanges(minSize);
1497     return SUCCESS;
1498 }
1499 
DrainAudioStream(bool stopFlag)1500 bool RendererInClientInner::DrainAudioStream(bool stopFlag)
1501 {
1502     std::lock_guard<std::mutex> statusLock(statusMutex_);
1503     std::lock_guard<std::mutex> lock(writeMutex_);
1504     bool ret = DrainAudioStreamInner(stopFlag);
1505     return ret;
1506 }
1507 
SetPreferredFrameSize(int32_t frameSize)1508 void RendererInClientInner::SetPreferredFrameSize(int32_t frameSize)
1509 {
1510     std::lock_guard<std::mutex> lockSetPreferredFrameSize(setPreferredFrameSizeMutex_);
1511     userSettedPreferredFrameSize_ = frameSize;
1512     CHECK_AND_RETURN_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID,
1513         "playing audiovivid, frameSize is always 1024.");
1514     size_t maxCbBufferSize =
1515         static_cast<size_t>(MAX_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1516     size_t minCbBufferSize =
1517         static_cast<size_t>(MIN_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1518     size_t preferredCbBufferSize = static_cast<size_t>(frameSize) * sizePerFrameInByte_;
1519     std::lock_guard<std::mutex> lock(cbBufferMutex_);
1520     cbBufferSize_ = (preferredCbBufferSize > maxCbBufferSize || preferredCbBufferSize < minCbBufferSize) ?
1521         (preferredCbBufferSize > maxCbBufferSize ? maxCbBufferSize : minCbBufferSize) : preferredCbBufferSize;
1522     AUDIO_INFO_LOG("Set CallbackBuffer with byte size: %{public}zu", cbBufferSize_);
1523     cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_);
1524     return;
1525 }
1526 
Write(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1527 int32_t RendererInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1528     size_t metaBufferSize)
1529 {
1530     CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1531         "Write with callback is not supported");
1532     int32_t ret = WriteInner(pcmBuffer, pcmBufferSize, metaBuffer, metaBufferSize);
1533     return ret <= 0 ? ret : static_cast<int32_t>(pcmBufferSize);
1534 }
1535 
Write(uint8_t * buffer,size_t bufferSize)1536 int32_t RendererInClientInner::Write(uint8_t *buffer, size_t bufferSize)
1537 {
1538     CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1539         "Write with callback is not supported");
1540     return WriteInner(buffer, bufferSize);
1541 }
1542 
ProcessSpeed(uint8_t * & buffer,size_t & bufferSize,bool & speedCached)1543 bool RendererInClientInner::ProcessSpeed(uint8_t *&buffer, size_t &bufferSize, bool &speedCached)
1544 {
1545     speedCached = false;
1546 #ifdef SONIC_ENABLE
1547     if (!isEqual(speed_, 1.0f)) {
1548         Trace trace(traceTag_ + " ProcessSpeed");
1549         if (audioSpeed_ == nullptr) {
1550             AUDIO_ERR_LOG("audioSpeed_ is nullptr, use speed default 1.0");
1551             return true;
1552         }
1553         int32_t outBufferSize = 0;
1554         if (audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, speedBuffer_, outBufferSize) == 0) {
1555             bufferSize = 0;
1556             AUDIO_ERR_LOG("process speed error");
1557             return false;
1558         }
1559         if (outBufferSize == 0) {
1560             AUDIO_DEBUG_LOG("speed buffer is not full");
1561             return false;
1562         }
1563         buffer = speedBuffer_.get();
1564         bufferSize = static_cast<size_t>(outBufferSize);
1565         speedCached = true;
1566     }
1567 #endif
1568     return true;
1569 }
1570 
DfxWriteInterval()1571 void RendererInClientInner::DfxWriteInterval()
1572 {
1573     if (preWriteEndTime_ != 0 &&
1574         ((ClockTime::GetCurNano() / AUDIO_US_PER_SECOND) - preWriteEndTime_) > MAX_WRITE_INTERVAL_MS) {
1575         AUDIO_WARNING_LOG("[%{public}s] write interval too long cost %{public}" PRId64,
1576             logUtilsTag_.c_str(), (ClockTime::GetCurNano() / AUDIO_US_PER_SECOND) - preWriteEndTime_);
1577     }
1578 }
WriteInner(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1579 int32_t RendererInClientInner::WriteInner(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1580     size_t metaBufferSize)
1581 {
1582     Trace trace("RendererInClient::Write with meta " + std::to_string(pcmBufferSize));
1583     CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding == ENCODING_AUDIOVIVID, ERR_NOT_SUPPORTED,
1584         "Write: Write not supported. encoding doesnot match.");
1585     BufferDesc bufDesc = {pcmBuffer, pcmBufferSize, pcmBufferSize, metaBuffer, metaBufferSize};
1586     CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_WRITE_FAILED, "Write: converter isn't init.");
1587     CHECK_AND_RETURN_RET_LOG(converter_->CheckInputValid(bufDesc), ERR_INVALID_PARAM, "Write: Invalid input.");
1588 
1589     WriteMuteDataSysEvent(pcmBuffer, pcmBufferSize);
1590 
1591     converter_->Process(bufDesc);
1592     uint8_t *buffer;
1593     uint32_t bufferSize;
1594     converter_->GetOutputBufferStream(buffer, bufferSize);
1595     return WriteInner(buffer, bufferSize);
1596 }
1597 
FirstFrameProcess()1598 void RendererInClientInner::FirstFrameProcess()
1599 {
1600     // if first call, call set thread priority. if thread tid change recall set thread priority
1601     if (needSetThreadPriority_) {
1602         ipcStream_->RegisterThreadPriority(gettid(),
1603             AudioSystemManager::GetInstance()->GetSelfBundleName(clientConfig_.appInfo.appUid));
1604         needSetThreadPriority_ = false;
1605     }
1606 
1607     if (!hasFirstFrameWrited_) { OnFirstFrameWriting(); }
1608 }
1609 
WriteRingCache(uint8_t * buffer,size_t bufferSize,bool speedCached,size_t oriBufferSize)1610 int32_t RendererInClientInner::WriteRingCache(uint8_t *buffer, size_t bufferSize, bool speedCached,
1611     size_t oriBufferSize)
1612 {
1613     size_t targetSize = bufferSize;
1614     size_t offset = 0;
1615     while (targetSize >= sizePerFrameInByte_) {
1616         // 1. write data into ring cache
1617         OptResult result = ringCache_->GetWritableSize();
1618         CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, speedCached ? oriBufferSize : bufferSize - targetSize,
1619             "RingCache write status invalid size is:%{public}zu", result.size);
1620 
1621         size_t writableSize = result.size;
1622         Trace::Count("RendererInClient::CacheBuffer->writableSize", writableSize);
1623 
1624         size_t writeSize = std::min(writableSize, targetSize);
1625         BufferWrap bufferWrap = {buffer + offset, writeSize};
1626 
1627         if (writeSize > 0) {
1628             result = ringCache_->Enqueue(bufferWrap);
1629             if (result.ret != OPERATION_SUCCESS) {
1630                 // in plan: recall enqueue in some cases
1631                 AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size);
1632                 break;
1633             }
1634             offset += writeSize;
1635             targetSize -= writeSize;
1636             clientWrittenBytes_ += writeSize;
1637         }
1638 
1639         // 2. copy data from cache to OHAudioBuffer
1640         result = ringCache_->GetReadableSize();
1641         CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, speedCached ? oriBufferSize : bufferSize - targetSize,
1642             "RingCache read status invalid size is:%{public}zu", result.size);
1643         size_t readableSize = result.size;
1644         Trace::Count("RendererInClient::CacheBuffer->readableSize", readableSize);
1645 
1646         if (readableSize < clientSpanSizeInByte_) { continue; }
1647         // if readable size is enough, we will call write data to server
1648         int32_t ret = WriteCacheData();
1649         CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE, speedCached ? oriBufferSize : bufferSize - targetSize,
1650             "Status changed while write");
1651         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "WriteCacheData failed %{public}d", ret);
1652     }
1653     preWriteEndTime_ = ClockTime::GetCurNano() / AUDIO_US_PER_SECOND;
1654     return speedCached ? oriBufferSize : bufferSize - targetSize;
1655 }
1656 
WriteInner(uint8_t * buffer,size_t bufferSize)1657 int32_t RendererInClientInner::WriteInner(uint8_t *buffer, size_t bufferSize)
1658 {
1659     // eg: RendererInClient::sessionId:100001 WriteSize:3840
1660     DfxWriteInterval();
1661     Trace trace(traceTag_+ " WriteSize:" + std::to_string(bufferSize));
1662     CHECK_AND_RETURN_RET_LOG(buffer != nullptr && bufferSize < MAX_WRITE_SIZE && bufferSize > 0, ERR_INVALID_PARAM,
1663         "invalid size is %{public}zu", bufferSize);
1664     Trace::CountVolume(traceTag_, *buffer);
1665     if (gServerProxy_ == nullptr && getuid() == MEDIA_SERVICE_UID) {
1666         uint32_t samplingRate = clientConfig_.streamInfo.samplingRate;
1667         uint32_t channels = clientConfig_.streamInfo.channels;
1668         uint32_t samplePerFrame = Util::GetSamplePerFrame(clientConfig_.streamInfo.format);
1669         // calculate wait time by buffer size, 10e6 is converting seconds to microseconds
1670         uint32_t waitTimeUs = bufferSize * 10e6 / (samplingRate * channels * samplePerFrame);
1671         AUDIO_ERR_LOG("server is died! wait %{public}d us", waitTimeUs);
1672         usleep(waitTimeUs);
1673         return ERR_WRITE_BUFFER;
1674     }
1675 
1676     CHECK_AND_RETURN_RET_LOG(gServerProxy_ != nullptr, ERROR, "server is died");
1677     if (clientBuffer_->GetStreamStatus() == nullptr) {
1678         AUDIO_ERR_LOG("The stream status is null!");
1679         return ERR_INVALID_PARAM;
1680     }
1681 
1682     if (clientBuffer_->GetStreamStatus()->load() == STREAM_STAND_BY) {
1683         Trace trace2(traceTag_+ " call start to exit stand-by");
1684         CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERROR, "ipcStream is not inited!");
1685         int32_t ret = ipcStream_->Start();
1686         AUDIO_INFO_LOG("%{public}u call start to exit stand-by ret %{public}u", sessionId_, ret);
1687     }
1688     std::lock_guard<std::mutex> lock(writeMutex_);
1689 
1690     size_t oriBufferSize = bufferSize;
1691     bool speedCached = false;
1692     if (!ProcessSpeed(buffer, bufferSize, speedCached)) {
1693         return bufferSize;
1694     }
1695 
1696     WriteMuteDataSysEvent(buffer, bufferSize);
1697 
1698     FirstFrameProcess();
1699 
1700     CHECK_AND_RETURN_RET_PRELOG(state_ == RUNNING, ERR_ILLEGAL_STATE,
1701         "Write: Illegal state:%{public}u sessionid: %{public}u", state_.load(), sessionId_);
1702 
1703     // hold lock
1704     if (isBlendSet_) {
1705         audioBlend_.Process(buffer, bufferSize);
1706     }
1707 
1708     return WriteRingCache(buffer, bufferSize, speedCached, oriBufferSize);
1709 }
1710 
ResetFramePosition()1711 void RendererInClientInner::ResetFramePosition()
1712 {
1713     Trace trace("RendererInClientInner::ResetFramePosition");
1714     uint64_t timestampVal = 0;
1715     uint64_t latency = 0;
1716     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
1717     int32_t ret = ipcStream_->GetAudioPosition(lastFlushReadIndex_, timestampVal, latency);
1718     if (ret != SUCCESS) {
1719         AUDIO_PRERELEASE_LOGE("Get position failed: %{public}u", ret);
1720         return;
1721     }
1722     lastFramePosition_ = 0;
1723 }
1724 
WriteMuteDataSysEvent(uint8_t * buffer,size_t bufferSize)1725 void RendererInClientInner::WriteMuteDataSysEvent(uint8_t *buffer, size_t bufferSize)
1726 {
1727     if (silentModeAndMixWithOthers_) {
1728         return;
1729     }
1730     if (buffer[0] == 0) {
1731         if (startMuteTime_ == 0) {
1732             startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
1733         }
1734         std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
1735         if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isUpEvent_) {
1736             AUDIO_WARNING_LOG("write silent data for some time");
1737             isUpEvent_ = true;
1738             std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
1739                 Media::MediaMonitor::AUDIO, Media::MediaMonitor::BACKGROUND_SILENT_PLAYBACK,
1740                 Media::MediaMonitor::FREQUENCY_AGGREGATION_EVENT);
1741             bean->Add("CLIENT_UID", appUid_);
1742             Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
1743         }
1744     } else if (buffer[0] != 0 && startMuteTime_ != 0) {
1745         startMuteTime_ = 0;
1746     }
1747 }
1748 
DrainIncompleteFrame(OptResult result,bool stopFlag,size_t targetSize,BufferDesc * desc,bool & dropFlag)1749 int32_t RendererInClientInner::DrainIncompleteFrame(OptResult result, bool stopFlag,
1750     size_t targetSize, BufferDesc *desc, bool &dropFlag)
1751 {
1752     if (result.size < clientSpanSizeInByte_ && stopFlag) {
1753         result = ringCache_->Dequeue({desc->buffer, targetSize});
1754         CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1755             "ringCache Dequeue failed %{public}d", result.ret);
1756         int32_t ret = memset_s(desc->buffer, targetSize, 0, targetSize);
1757         CHECK_AND_RETURN_RET_LOG(ret == EOK, ERROR, "DrainIncompleteFrame memset output failed");
1758         AUDIO_WARNING_LOG("incomplete frame is set to 0");
1759         dropFlag = true;
1760     }
1761     return SUCCESS;
1762 }
1763 
1764 
WriteCacheData(bool isDrain,bool stopFlag)1765 int32_t RendererInClientInner::WriteCacheData(bool isDrain, bool stopFlag)
1766 {
1767     Trace traceCache(isDrain ? "RendererInClientInner::DrainCacheData" : "RendererInClientInner::WriteCacheData");
1768 
1769     OptResult result = ringCache_->GetReadableSize();
1770     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_OPERATION_FAILED, "ring cache unreadable");
1771     CHECK_AND_RETURN_RET_LOG(result.size != 0, SUCCESS, "Readable size is already zero");
1772 
1773     size_t targetSize = isDrain ? std::min(result.size, clientSpanSizeInByte_) : clientSpanSizeInByte_;
1774 
1775     int32_t sizeInFrame = clientBuffer_->GetAvailableDataFrames();
1776     CHECK_AND_RETURN_RET_LOG(sizeInFrame >= 0, ERROR, "GetAvailableDataFrames invalid, %{public}d", sizeInFrame);
1777 
1778     int32_t tryCount = 2; // try futex wait for 2 times.
1779     FutexCode futexRes = FUTEX_OPERATION_FAILED;
1780     while (static_cast<uint32_t>(sizeInFrame) < spanSizeInFrame_ && tryCount > 0) {
1781         tryCount--;
1782         int32_t timeout = offloadEnable_ ? OFFLOAD_OPERATION_TIMEOUT_IN_MS : WRITE_CACHE_TIMEOUT_IN_MS;
1783         futexRes = FutexTool::FutexWait(clientBuffer_->GetFutex(), static_cast<int64_t>(timeout) * AUDIO_US_PER_SECOND);
1784         CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "failed with state:%{public}d", state_.load());
1785         CHECK_AND_RETURN_RET_LOG(futexRes != FUTEX_TIMEOUT, ERROR,
1786             "write data time out, mode is %{public}s", (offloadEnable_ ? "offload" : "normal"));
1787         sizeInFrame = clientBuffer_->GetAvailableDataFrames();
1788         if (futexRes == FUTEX_SUCCESS && sizeInFrame > 0) { break; }
1789     }
1790 
1791     if (sizeInFrame < 0 || static_cast<uint32_t>(clientBuffer_->GetAvailableDataFrames()) < spanSizeInFrame_) {
1792         AUDIO_ERR_LOG("failed: sizeInFrame is:%{public}d, futexRes:%{public}d", sizeInFrame, futexRes);
1793         return ERROR;
1794     }
1795     BufferDesc desc = {};
1796     uint64_t curWriteIndex = clientBuffer_->GetCurWriteFrame();
1797     int32_t ret = clientBuffer_->GetWriteBuffer(curWriteIndex, desc);
1798     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "GetWriteBuffer failed %{public}d", ret);
1799     bool dropFlag = false;
1800     CHECK_AND_RETURN_RET(DrainIncompleteFrame(result, stopFlag, targetSize, &desc, dropFlag) == SUCCESS, ERROR);
1801     if (dropFlag) {
1802         return SUCCESS;
1803     }
1804     result = ringCache_->Dequeue({desc.buffer, targetSize});
1805     CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "ringCache Dequeue failed %{public}d", result.ret);
1806 
1807     // volume process in client
1808     if (volumeRamp_.IsActive()) {
1809         // do not call SetVolume here.
1810         clientVolume_ = volumeRamp_.GetRampVolume();
1811         AUDIO_INFO_LOG("clientVolume_:%{public}f", clientVolume_);
1812         Trace traceVolume("RendererInClientInner::WriteCacheData:Ramp:clientVolume_:" + std::to_string(clientVolume_));
1813         CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
1814         clientBuffer_->SetStreamVolume(clientVolume_);
1815     }
1816 
1817     DumpFileUtil::WriteDumpFile(dumpOutFd_, static_cast<void *>(desc.buffer), desc.bufLength);
1818     DfxOperation(desc, clientConfig_.streamInfo.format, clientConfig_.streamInfo.channels);
1819     clientBuffer_->SetCurWriteFrame(curWriteIndex + spanSizeInFrame_);
1820 
1821     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "WriteCacheData failed, null ipcStream_.");
1822     ipcStream_->UpdatePosition(); // notiify server update position
1823     HandleRendererPositionChanges(desc.bufLength);
1824     return SUCCESS;
1825 }
1826 
DfxOperation(BufferDesc & buffer,AudioSampleFormat format,AudioChannel channel) const1827 void RendererInClientInner::DfxOperation(BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel) const
1828 {
1829     ChannelVolumes vols = VolumeTools::CountVolumeLevel(buffer, format, channel);
1830     if (channel == MONO) {
1831         Trace::Count(logUtilsTag_, vols.volStart[0]);
1832     } else {
1833         Trace::Count(logUtilsTag_, (vols.volStart[0] + vols.volStart[1]) / HALF_FACTOR);
1834     }
1835     AudioLogUtils::ProcessVolumeData(logUtilsTag_, vols, volumeDataCount_);
1836 }
1837 
HandleRendererPositionChanges(size_t bytesWritten)1838 void RendererInClientInner::HandleRendererPositionChanges(size_t bytesWritten)
1839 {
1840     totalBytesWritten_ += static_cast<int64_t>(bytesWritten);
1841     if (sizePerFrameInByte_ == 0) {
1842         AUDIO_ERR_LOG("HandleRendererPositionChanges: sizePerFrameInByte_ is 0");
1843         return;
1844     }
1845     int64_t writtenFrameNumber = totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1846     AUDIO_DEBUG_LOG("frame size: %{public}zu", sizePerFrameInByte_);
1847 
1848     {
1849         std::lock_guard<std::mutex> lock(markReachMutex_);
1850         if (!rendererMarkReached_) {
1851             AUDIO_DEBUG_LOG("Frame mark position: %{public}" PRId64", Total frames written: %{public}" PRId64,
1852                 static_cast<int64_t>(rendererMarkPosition_), static_cast<int64_t>(writtenFrameNumber));
1853             if (writtenFrameNumber >= rendererMarkPosition_) {
1854                 AUDIO_DEBUG_LOG("OnMarkReached %{public}" PRId64".", rendererMarkPosition_);
1855                 SendRenderMarkReachedEvent(rendererMarkPosition_);
1856                 rendererMarkReached_ = true;
1857             }
1858         }
1859     }
1860 
1861     {
1862         std::lock_guard<std::mutex> lock(periodReachMutex_);
1863         rendererPeriodWritten_ += static_cast<int64_t>((bytesWritten / sizePerFrameInByte_));
1864         AUDIO_DEBUG_LOG("Frame period number: %{public}" PRId64", Total frames written: %{public}" PRId64,
1865             static_cast<int64_t>(rendererPeriodWritten_), static_cast<int64_t>(totalBytesWritten_));
1866         if (rendererPeriodWritten_ >= rendererPeriodSize_ && rendererPeriodSize_ > 0) {
1867             rendererPeriodWritten_ %= rendererPeriodSize_;
1868             AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRId64,
1869                 static_cast<int64_t>(rendererPeriodWritten_));
1870             SendRenderPeriodReachedEvent(rendererPeriodSize_);
1871         }
1872     }
1873 }
1874 
1875 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedEvent(int64_t rendererMarkPosition)1876 void RendererInClientInner::SendRenderMarkReachedEvent(int64_t rendererMarkPosition)
1877 {
1878     SafeSendCallbackEvent(RENDERER_MARK_REACHED_EVENT, rendererMarkPosition);
1879 }
1880 
1881 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)1882 void RendererInClientInner::SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)
1883 {
1884     SafeSendCallbackEvent(RENDERER_PERIOD_REACHED_EVENT, rendererPeriodSize);
1885 }
1886 
ParamsToStateCmdType(int64_t params,State & state,StateChangeCmdType & cmdType)1887 int32_t RendererInClientInner::ParamsToStateCmdType(int64_t params, State &state, StateChangeCmdType &cmdType)
1888 {
1889     cmdType = CMD_FROM_CLIENT;
1890     switch (params) {
1891         case HANDLER_PARAM_NEW:
1892             state = NEW;
1893             break;
1894         case HANDLER_PARAM_PREPARED:
1895             state = PREPARED;
1896             break;
1897         case HANDLER_PARAM_RUNNING:
1898             state = RUNNING;
1899             break;
1900         case HANDLER_PARAM_STOPPED:
1901             state = STOPPED;
1902             break;
1903         case HANDLER_PARAM_RELEASED:
1904             state = RELEASED;
1905             break;
1906         case HANDLER_PARAM_PAUSED:
1907             state = PAUSED;
1908             break;
1909         case HANDLER_PARAM_STOPPING:
1910             state = STOPPING;
1911             break;
1912         case HANDLER_PARAM_RUNNING_FROM_SYSTEM:
1913             state = RUNNING;
1914             cmdType = CMD_FROM_SYSTEM;
1915             break;
1916         case HANDLER_PARAM_PAUSED_FROM_SYSTEM:
1917             state = PAUSED;
1918             cmdType = CMD_FROM_SYSTEM;
1919             break;
1920         default:
1921             state = INVALID;
1922             break;
1923     }
1924     return SUCCESS;
1925 }
1926 
StateCmdTypeToParams(int64_t & params,State state,StateChangeCmdType cmdType)1927 int32_t RendererInClientInner::StateCmdTypeToParams(int64_t &params, State state, StateChangeCmdType cmdType)
1928 {
1929     if (cmdType == CMD_FROM_CLIENT) {
1930         params = static_cast<int64_t>(state);
1931         return SUCCESS;
1932     }
1933     switch (state) {
1934         case RUNNING:
1935             params = HANDLER_PARAM_RUNNING_FROM_SYSTEM;
1936             break;
1937         case PAUSED:
1938             params = HANDLER_PARAM_PAUSED_FROM_SYSTEM;
1939             break;
1940         default:
1941             params = HANDLER_PARAM_INVALID;
1942             break;
1943     }
1944     return SUCCESS;
1945 }
1946 
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)1947 int32_t RendererInClientInner::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
1948 {
1949     AUDIO_ERR_LOG("Read is not supported");
1950     return ERROR;
1951 }
1952 
1953 
GetUnderflowCount()1954 uint32_t RendererInClientInner::GetUnderflowCount()
1955 {
1956     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, 0, "buffer is not inited");
1957 
1958     return clientBuffer_->GetUnderrunCount();
1959 }
1960 
GetOverflowCount()1961 uint32_t RendererInClientInner::GetOverflowCount()
1962 {
1963     AUDIO_WARNING_LOG("No Overflow in renderer");
1964     return 0;
1965 }
1966 
SetUnderflowCount(uint32_t underflowCount)1967 void RendererInClientInner::SetUnderflowCount(uint32_t underflowCount)
1968 {
1969     CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "buffer is not inited");
1970     clientBuffer_->SetUnderrunCount(underflowCount);
1971 }
1972 
SetOverflowCount(uint32_t overflowCount)1973 void RendererInClientInner::SetOverflowCount(uint32_t overflowCount)
1974 {
1975     // not support for renderer
1976     AUDIO_WARNING_LOG("No Overflow in renderer");
1977     return;
1978 }
1979 
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1980 void RendererInClientInner::SetRendererPositionCallback(int64_t markPosition,
1981     const std::shared_ptr<RendererPositionCallback> &callback)
1982 {
1983     // waiting for review
1984     std::lock_guard<std::mutex> lock(markReachMutex_);
1985     CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPositionCallback is nullptr");
1986     rendererPositionCallback_ = callback;
1987     rendererMarkPosition_ = markPosition;
1988     rendererMarkReached_ = false;
1989 }
1990 
UnsetRendererPositionCallback()1991 void RendererInClientInner::UnsetRendererPositionCallback()
1992 {
1993     // waiting for review
1994     std::lock_guard<std::mutex> lock(markReachMutex_);
1995     rendererPositionCallback_ = nullptr;
1996     rendererMarkPosition_ = 0;
1997     rendererMarkReached_ = false;
1998 }
1999 
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)2000 void RendererInClientInner::SetRendererPeriodPositionCallback(int64_t periodPosition,
2001     const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2002 {
2003     // waiting for review
2004     std::lock_guard<std::mutex> lock(periodReachMutex_);
2005     CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPeriodPositionCallback is nullptr");
2006     rendererPeriodPositionCallback_ = callback;
2007     rendererPeriodSize_ = periodPosition;
2008     totalBytesWritten_ = 0;
2009     rendererPeriodWritten_ = 0;
2010 }
2011 
UnsetRendererPeriodPositionCallback()2012 void RendererInClientInner::UnsetRendererPeriodPositionCallback()
2013 {
2014     // waiting for review
2015     std::lock_guard<std::mutex> lock(periodReachMutex_);
2016     rendererPeriodPositionCallback_ = nullptr;
2017     rendererPeriodSize_ = 0;
2018     totalBytesWritten_ = 0;
2019     rendererPeriodWritten_ = 0;
2020 }
2021 
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)2022 void RendererInClientInner::SetCapturerPositionCallback(int64_t markPosition,
2023     const std::shared_ptr<CapturerPositionCallback> &callback)
2024 {
2025     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2026     return;
2027 }
2028 
UnsetCapturerPositionCallback()2029 void RendererInClientInner::UnsetCapturerPositionCallback()
2030 {
2031     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2032     return;
2033 }
2034 
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2035 void RendererInClientInner::SetCapturerPeriodPositionCallback(int64_t periodPosition,
2036     const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2037 {
2038     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2039     return;
2040 }
2041 
UnsetCapturerPeriodPositionCallback()2042 void RendererInClientInner::UnsetCapturerPeriodPositionCallback()
2043 {
2044     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2045     return;
2046 }
2047 
SetRendererSamplingRate(uint32_t sampleRate)2048 int32_t RendererInClientInner::SetRendererSamplingRate(uint32_t sampleRate)
2049 {
2050     AUDIO_ERR_LOG("SetRendererSamplingRate to %{public}d is not supported", sampleRate);
2051     return ERROR;
2052 }
2053 
GetRendererSamplingRate()2054 uint32_t RendererInClientInner::GetRendererSamplingRate()
2055 {
2056     return curStreamParams_.samplingRate;
2057 }
2058 
SetBufferSizeInMsec(int32_t bufferSizeInMsec)2059 int32_t RendererInClientInner::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
2060 {
2061     // bufferSizeInMsec is checked between 5ms and 20ms.
2062     bufferSizeInMsec_ = static_cast<uint32_t>(bufferSizeInMsec);
2063     AUDIO_INFO_LOG("SetBufferSizeInMsec to %{public}d", bufferSizeInMsec_);
2064     if (renderMode_ == RENDER_MODE_CALLBACK) {
2065         uint64_t bufferDurationInUs = bufferSizeInMsec_ * AUDIO_US_PER_MS;
2066         InitCallbackBuffer(bufferDurationInUs);
2067     }
2068     return SUCCESS;
2069 }
2070 
SetApplicationCachePath(const std::string cachePath)2071 void RendererInClientInner::SetApplicationCachePath(const std::string cachePath)
2072 {
2073     cachePath_ = cachePath;
2074     AUDIO_INFO_LOG("SetApplicationCachePath to %{public}s", cachePath_.c_str());
2075 }
2076 
SetChannelBlendMode(ChannelBlendMode blendMode)2077 int32_t RendererInClientInner::SetChannelBlendMode(ChannelBlendMode blendMode)
2078 {
2079     if ((state_ != PREPARED) && (state_ != NEW)) {
2080         AUDIO_ERR_LOG("SetChannelBlendMode in invalid status:%{public}d", state_.load());
2081         return ERR_ILLEGAL_STATE;
2082     }
2083     isBlendSet_ = true;
2084     audioBlend_.SetParams(blendMode, curStreamParams_.format, curStreamParams_.channels);
2085     return SUCCESS;
2086 }
2087 
SetVolumeWithRamp(float volume,int32_t duration)2088 int32_t RendererInClientInner::SetVolumeWithRamp(float volume, int32_t duration)
2089 {
2090     CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != INVALID) && (state_ != STOPPED),
2091         ERR_ILLEGAL_STATE, "Illegal state state %{public}d", state_.load());
2092 
2093     if (FLOAT_COMPARE_EQ(clientVolume_, volume)) {
2094         AUDIO_INFO_LOG("set same volume %{public}f", volume);
2095         return SUCCESS;
2096     }
2097 
2098     volumeRamp_.SetVolumeRampConfig(volume, clientVolume_, duration);
2099     return SUCCESS;
2100 }
2101 
SetStreamTrackerState(bool trackerRegisteredState)2102 void RendererInClientInner::SetStreamTrackerState(bool trackerRegisteredState)
2103 {
2104     streamTrackerRegistered_ = trackerRegisteredState;
2105 }
2106 
GetSwitchInfo(IAudioStream::SwitchInfo & info)2107 void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info)
2108 {
2109     info.params = streamParams_;
2110 
2111     info.rendererInfo = rendererInfo_;
2112     info.capturerInfo = capturerInfo_;
2113     info.eStreamType = eStreamType_;
2114     info.renderMode = renderMode_;
2115     info.state = state_;
2116     info.sessionId = sessionId_;
2117     info.streamTrackerRegistered = streamTrackerRegistered_;
2118     GetStreamSwitchInfo(info);
2119 
2120     {
2121         std::lock_guard<std::mutex> lock(setPreferredFrameSizeMutex_);
2122         info.userSettedPreferredFrameSize = userSettedPreferredFrameSize_;
2123     }
2124 }
2125 
GetStreamSwitchInfo(IAudioStream::SwitchInfo & info)2126 void RendererInClientInner::GetStreamSwitchInfo(IAudioStream::SwitchInfo& info)
2127 {
2128     info.cachePath = cachePath_;
2129     info.underFlowCount = GetUnderflowCount();
2130     info.effectMode = effectMode_;
2131     info.renderRate = rendererRate_;
2132     info.clientPid = clientPid_;
2133     info.clientUid = clientUid_;
2134     info.volume = clientVolume_;
2135     info.silentModeAndMixWithOthers = silentModeAndMixWithOthers_;
2136 
2137     info.frameMarkPosition = static_cast<uint64_t>(rendererMarkPosition_);
2138     info.renderPositionCb = rendererPositionCallback_;
2139 
2140     info.framePeriodNumber = static_cast<uint64_t>(rendererPeriodSize_);
2141     info.renderPeriodPositionCb = rendererPeriodPositionCallback_;
2142 
2143     info.rendererWriteCallback = writeCb_;
2144 }
2145 
GetStreamClass()2146 IAudioStream::StreamClass RendererInClientInner::GetStreamClass()
2147 {
2148     return PA_STREAM;
2149 }
2150 
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)2151 void RendererInClientInner::OnSpatializationStateChange(const AudioSpatializationState &spatializationState)
2152 {
2153     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
2154     CHECK_AND_RETURN_LOG(ipcStream_->UpdateSpatializationState(spatializationState.spatializationEnabled,
2155         spatializationState.headTrackingEnabled) == SUCCESS, "Update spatialization state failed");
2156 }
2157 
GetOffloadEnable()2158 bool RendererInClientInner::GetOffloadEnable()
2159 {
2160     return offloadEnable_;
2161 }
2162 
GetSpatializationEnabled()2163 bool RendererInClientInner::GetSpatializationEnabled()
2164 {
2165     return rendererInfo_.spatializationEnabled;
2166 }
2167 
GetHighResolutionEnabled()2168 bool RendererInClientInner::GetHighResolutionEnabled()
2169 {
2170     return AudioPolicyManager::GetInstance().IsHighResolutionExist();
2171 }
2172 
RegisterSpatializationStateEventListener()2173 int32_t RendererInClientInner::RegisterSpatializationStateEventListener()
2174 {
2175     if (firstSpatializationRegistered_) {
2176         firstSpatializationRegistered_ = false;
2177     } else {
2178         UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
2179     }
2180 
2181     if (!spatializationStateChangeCallback_) {
2182         spatializationStateChangeCallback_ = std::make_shared<SpatializationStateChangeCallbackImpl>();
2183         CHECK_AND_RETURN_RET_LOG(spatializationStateChangeCallback_, ERROR, "Memory Allocation Failed !!");
2184     }
2185     spatializationStateChangeCallback_->SetRendererInClientPtr(shared_from_this());
2186 
2187     int32_t ret = AudioPolicyManager::GetInstance().RegisterSpatializationStateEventListener(
2188         sessionId_, rendererInfo_.streamUsage, spatializationStateChangeCallback_);
2189     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "RegisterSpatializationStateEventListener failed");
2190     spatializationRegisteredSessionID_ = sessionId_;
2191 
2192     return SUCCESS;
2193 }
2194 
UnregisterSpatializationStateEventListener(uint32_t sessionID)2195 int32_t RendererInClientInner::UnregisterSpatializationStateEventListener(uint32_t sessionID)
2196 {
2197     int32_t ret = AudioPolicyManager::GetInstance().UnregisterSpatializationStateEventListener(sessionID);
2198     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "UnregisterSpatializationStateEventListener failed");
2199     return SUCCESS;
2200 }
2201 
DrainAudioStreamInner(bool stopFlag)2202 bool RendererInClientInner::DrainAudioStreamInner(bool stopFlag)
2203 {
2204     Trace trace("RendererInClientInner::DrainAudioStreamInner " + std::to_string(sessionId_));
2205     CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Drain failed. Illegal state:%{public}u", state_.load());
2206     CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed");
2207 
2208     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
2209     AUDIO_INFO_LOG("stopFlag:%{public}d", stopFlag);
2210     int32_t ret = ipcStream_->Drain(stopFlag);
2211     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Drain call server failed:%{public}u", ret);
2212     std::unique_lock<std::mutex> waitLock(callServerMutex_);
2213     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
2214         return notifiedOperation_ == DRAIN_STREAM; // will be false when got notified.
2215     });
2216 
2217     if (notifiedOperation_ != DRAIN_STREAM || notifiedResult_ != SUCCESS) {
2218         AUDIO_ERR_LOG("Drain failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
2219             (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
2220         notifiedOperation_ = MAX_OPERATION_CODE;
2221         return false;
2222     }
2223     notifiedOperation_ = MAX_OPERATION_CODE;
2224     waitLock.unlock();
2225     AUDIO_INFO_LOG("Drain stream SUCCESS, sessionId: %{public}d", sessionId_);
2226     return true;
2227 }
2228 
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)2229 void RendererInClientInner::UpdateLatencyTimestamp(std::string &timestamp, bool isRenderer)
2230 {
2231     sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
2232     if (gasp == nullptr) {
2233         AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
2234         return;
2235     }
2236     gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
2237 }
2238 
SetSilentModeAndMixWithOthers(bool on)2239 void RendererInClientInner::SetSilentModeAndMixWithOthers(bool on)
2240 {
2241     AUDIO_PRERELEASE_LOGI("SetSilentModeAndMixWithOthers %{public}d", on);
2242     silentModeAndMixWithOthers_ = on;
2243     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
2244     ipcStream_->SetSilentModeAndMixWithOthers(on);
2245     return;
2246 }
2247 
GetSilentModeAndMixWithOthers()2248 bool RendererInClientInner::GetSilentModeAndMixWithOthers()
2249 {
2250     return silentModeAndMixWithOthers_;
2251 }
2252 
SpatializationStateChangeCallbackImpl()2253 SpatializationStateChangeCallbackImpl::SpatializationStateChangeCallbackImpl()
2254 {
2255     AUDIO_INFO_LOG("Instance create");
2256 }
2257 
~SpatializationStateChangeCallbackImpl()2258 SpatializationStateChangeCallbackImpl::~SpatializationStateChangeCallbackImpl()
2259 {
2260     AUDIO_INFO_LOG("Instance destory");
2261 }
2262 
SetRendererInClientPtr(std::shared_ptr<RendererInClientInner> rendererInClientPtr)2263 void SpatializationStateChangeCallbackImpl::SetRendererInClientPtr(
2264     std::shared_ptr<RendererInClientInner> rendererInClientPtr)
2265 {
2266     rendererInClientPtr_ = rendererInClientPtr;
2267 }
2268 
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)2269 void SpatializationStateChangeCallbackImpl::OnSpatializationStateChange(
2270     const AudioSpatializationState &spatializationState)
2271 {
2272     std::shared_ptr<RendererInClientInner> rendererInClient = rendererInClientPtr_.lock();
2273     if (rendererInClient != nullptr) {
2274         rendererInClient->OnSpatializationStateChange(spatializationState);
2275     }
2276 }
2277 
RestoreAudioStream(bool needStoreState)2278 bool RendererInClientInner::RestoreAudioStream(bool needStoreState)
2279 {
2280     CHECK_AND_RETURN_RET_LOG(proxyObj_ != nullptr, false, "proxyObj_ is null");
2281     CHECK_AND_RETURN_RET_LOG(state_ != NEW && state_ != INVALID && state_ != RELEASED, true,
2282         "state_ is %{public}d, no need for restore", state_.load());
2283     bool result = false;
2284     State oldState = state_;
2285     state_ = NEW;
2286     SetStreamTrackerState(false);
2287     // If pipe type is offload, need reset to normal.
2288     // Otherwise, unable to enter offload mode.
2289     if (rendererInfo_.pipeType == PIPE_TYPE_OFFLOAD) {
2290         rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
2291     }
2292     int32_t ret = SetAudioStreamInfo(streamParams_, proxyObj_);
2293     if (ret != SUCCESS) {
2294         goto error;
2295     }
2296     if (!needStoreState) {
2297         AUDIO_INFO_LOG("telephony scene, return directly");
2298         return ret == SUCCESS;
2299     }
2300     switch (oldState) {
2301         case RUNNING:
2302             result = StartAudioStream();
2303             break;
2304         case PAUSED:
2305             result = StartAudioStream() && PauseAudioStream();
2306             break;
2307         case STOPPED:
2308         case STOPPING:
2309             result = StartAudioStream() && StopAudioStream();
2310             break;
2311         default:
2312             break;
2313     }
2314     if (!result) {
2315         goto error;
2316     }
2317     return result;
2318 
2319 error:
2320     AUDIO_ERR_LOG("RestoreAudioStream failed");
2321     state_ = oldState;
2322     return false;
2323 }
2324 } // namespace AudioStandard
2325 } // namespace OHOS
2326 #endif // FAST_AUDIO_STREAM_H
2327