• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "RendererInClientInnerPublic"
17 #endif
18 
19 #include "renderer_in_client.h"
20 #include "renderer_in_client_private.h"
21 
22 #include <atomic>
23 #include <cinttypes>
24 #include <condition_variable>
25 #include <sstream>
26 #include <string>
27 #include <mutex>
28 #include <thread>
29 
30 #include "iservice_registry.h"
31 #include "system_ability_definition.h"
32 #include "securec.h"
33 #include "hisysevent.h"
34 
35 #include "audio_errors.h"
36 #include "audio_policy_manager.h"
37 #include "audio_manager_base.h"
38 #include "audio_renderer_log.h"
39 #include "audio_ring_cache.h"
40 #include "audio_channel_blend.h"
41 #include "audio_server_death_recipient.h"
42 #include "audio_stream_tracker.h"
43 #include "audio_system_manager.h"
44 #include "futex_tool.h"
45 #include "ipc_stream_listener_impl.h"
46 #include "ipc_stream_listener_stub.h"
47 #include "volume_ramp.h"
48 #include "callback_handler.h"
49 #include "audio_speed.h"
50 #include "audio_spatial_channel_converter.h"
51 #include "audio_policy_manager.h"
52 #include "audio_spatialization_manager.h"
53 #include "policy_handler.h"
54 #include "volume_tools.h"
55 #include "audio_manager_util.h"
56 #include "audio_effect_map.h"
57 
58 #include "media_monitor_manager.h"
59 
60 using namespace OHOS::HiviewDFX;
61 using namespace OHOS::AppExecFwk;
62 
63 namespace OHOS {
64 namespace AudioStandard {
65 namespace {
66 const uint64_t OLD_BUF_DURATION_IN_USEC = 92880; // This value is used for compatibility purposes.
67 const uint64_t AUDIO_US_PER_MS = 1000;
68 const uint64_t AUDIO_NS_PER_US = 1000;
69 const uint64_t AUDIO_US_PER_S = 1000000;
70 const uint64_t AUDIO_MS_PER_S = 1000;
71 static constexpr int CB_QUEUE_CAPACITY = 3;
72 const uint64_t AUDIO_FIRST_FRAME_LATENCY = 120; //ms
73 static const int32_t CREATE_TIMEOUT_IN_SECOND = 9; // 9S
74 constexpr int32_t MAX_BUFFER_SIZE = 100000;
75 const uint64_t MAX_CBBUF_IN_USEC = 100000;
76 const uint64_t MIN_CBBUF_IN_USEC = 20000;
77 static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms
78 static const int32_t SHORT_TIMEOUT_IN_MS = 20; // ms
79 static const int32_t DATA_CONNECTION_TIMEOUT_IN_MS = 300; // ms
80 } // namespace
GetInstance(AudioStreamType eStreamType,int32_t appUid)81 std::shared_ptr<RendererInClient> RendererInClient::GetInstance(AudioStreamType eStreamType, int32_t appUid)
82 {
83     return std::make_shared<RendererInClientInner>(eStreamType, appUid);
84 }
85 
RendererInClientInner(AudioStreamType eStreamType,int32_t appUid)86 RendererInClientInner::RendererInClientInner(AudioStreamType eStreamType, int32_t appUid)
87     : eStreamType_(eStreamType), appUid_(appUid), cbBufferQueue_(CB_QUEUE_CAPACITY)
88 {
89     AUDIO_INFO_LOG("Create with StreamType:%{public}d appUid:%{public}d ", eStreamType_, appUid_);
90     audioStreamTracker_ = std::make_unique<AudioStreamTracker>(AUDIO_MODE_PLAYBACK, appUid);
91     state_ = NEW;
92 }
93 
~RendererInClientInner()94 RendererInClientInner::~RendererInClientInner()
95 {
96     AUDIO_INFO_LOG("~RendererInClientInner()");
97     DumpFileUtil::CloseDumpFile(&dumpOutFd_);
98     RendererInClientInner::ReleaseAudioStream(true);
99     std::lock_guard<std::mutex> runnerlock(runnerMutex_);
100     if (!runnerReleased_ && callbackHandler_ != nullptr) {
101         AUDIO_INFO_LOG("runner remove");
102         callbackHandler_->ReleaseEventRunner();
103         runnerReleased_ = true;
104         callbackHandler_ = nullptr;
105     }
106     UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
107     AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
108 }
109 
OnOperationHandled(Operation operation,int64_t result)110 int32_t RendererInClientInner::OnOperationHandled(Operation operation, int64_t result)
111 {
112     Trace trace(traceTag_ + " OnOperationHandled:" + std::to_string(operation));
113     AUDIO_INFO_LOG("sessionId %{public}d recv operation:%{public}d result:%{public}" PRId64".", sessionId_, operation,
114         result);
115     if (operation == SET_OFFLOAD_ENABLE) {
116         AUDIO_INFO_LOG("SET_OFFLOAD_ENABLE result:%{public}" PRId64".", result);
117         if (!offloadEnable_ && static_cast<bool>(result)) {
118             offloadStartReadPos_ = 0;
119         }
120         offloadEnable_ = static_cast<bool>(result);
121         rendererInfo_.pipeType = offloadEnable_ ? PIPE_TYPE_OFFLOAD : PIPE_TYPE_NORMAL_OUT;
122         return SUCCESS;
123     } else if (operation == DATA_LINK_CONNECTING) {
124         isDataLinkConnected_ = false;
125         return SUCCESS;
126     } else if (operation == DATA_LINK_CONNECTED) {
127         isDataLinkConnected_ = true;
128         dataConnectionCV_.notify_all();
129         return SUCCESS;
130     }
131 
132     if (operation == RESTORE_SESSION) {
133         // fix it when restoreAudioStream work right
134         if (audioStreamTracker_ && audioStreamTracker_.get()) {
135             audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_,
136                 state_, clientPid_, rendererInfo_, AudioStreamDeviceChangeReasonExt::ExtEnum::UNKNOWN);
137         }
138         return SUCCESS;
139     }
140 
141     std::unique_lock<std::mutex> lock(callServerMutex_);
142     notifiedOperation_ = operation;
143     notifiedResult_ = result;
144 
145     if (notifiedResult_ == SUCCESS) {
146         HandleStatusChangeOperation(operation);
147     } else {
148         AUDIO_ERR_LOG("operation %{public}d failed, result: %{public}" PRId64 "", operation, result);
149     }
150 
151     callServerCV_.notify_all();
152     return SUCCESS;
153 }
154 
HandleStatusChangeOperation(Operation operation)155 void RendererInClientInner::HandleStatusChangeOperation(Operation operation)
156 {
157     std::unique_lock<std::mutex> lock(streamCbMutex_);
158     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
159     switch (operation) {
160         case START_STREAM :
161             state_ = RUNNING;
162             break;
163         case PAUSE_STREAM :
164             state_ = PAUSED;
165             break;
166         case STOP_STREAM :
167             state_ = STOPPED;
168             break;
169         default :
170             break;
171     }
172     if (streamCb != nullptr) {
173         streamCb->OnStateChange(state_, CMD_FROM_SYSTEM);
174     }
175 }
176 
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId,uint64_t fullTokenId)177 void RendererInClientInner::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId, uint64_t fullTokenId)
178 {
179     AUDIO_INFO_LOG("PID:%{public}d UID:%{public}d.", clientPid, clientUid);
180     clientPid_ = clientPid;
181     clientUid_ = clientUid;
182     appTokenId_ = appTokenId;
183     fullTokenId_ = fullTokenId;
184 }
185 
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)186 int32_t RendererInClientInner::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
187 {
188     AUDIO_ERR_LOG("Unsupported operation!");
189     return ERR_NOT_SUPPORTED;
190 }
191 
SetRendererInfo(const AudioRendererInfo & rendererInfo)192 void RendererInClientInner::SetRendererInfo(const AudioRendererInfo &rendererInfo)
193 {
194     rendererInfo_ = rendererInfo;
195 
196     rendererInfo_.sceneType = AudioManagerUtil::GetEffectSceneName(rendererInfo_.streamUsage);
197 
198     const std::unordered_map<AudioEffectScene, std::string> &audioSupportedSceneTypes = GetSupportedSceneType();
199 
200     if (rendererInfo_.sceneType == audioSupportedSceneTypes.find(SCENE_OTHERS)->second) {
201         effectMode_ = EFFECT_NONE;
202         rendererInfo_.effectMode = EFFECT_NONE;
203     }
204 
205     AUDIO_PRERELEASE_LOGI("SetRendererInfo with flag %{public}d, sceneType %{public}s", rendererInfo_.rendererFlags,
206         rendererInfo_.sceneType.c_str());
207     AudioSpatializationState spatializationState =
208         AudioPolicyManager::GetInstance().GetSpatializationState(rendererInfo_.streamUsage);
209     rendererInfo_.spatializationEnabled = spatializationState.spatializationEnabled;
210     rendererInfo_.headTrackingEnabled = spatializationState.headTrackingEnabled;
211     rendererInfo_.encodingType = curStreamParams_.encoding;
212     rendererInfo_.channelLayout = curStreamParams_.channelLayout;
213     UpdateTracker("UPDATE");
214 }
215 
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)216 void RendererInClientInner::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
217 {
218     AUDIO_WARNING_LOG("SetCapturerInfo is not supported");
219     return;
220 }
221 
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj,const AudioPlaybackCaptureConfig & config)222 int32_t RendererInClientInner::SetAudioStreamInfo(const AudioStreamParams info,
223     const std::shared_ptr<AudioClientTracker> &proxyObj,
224     const AudioPlaybackCaptureConfig &config)
225 {
226     // In plan: If paramsIsSet_ is true, and new info is same as old info, return
227     AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
228         " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format,
229         eStreamType_, info.encoding);
230 
231     AudioXCollie guard("RendererInClientInner::SetAudioStreamInfo", CREATE_TIMEOUT_IN_SECOND);
232     if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
233         AUDIO_ERR_LOG("Unsupported audio parameter");
234         return ERR_NOT_SUPPORTED;
235     }
236 
237     streamParams_ = curStreamParams_ = info; // keep it for later use
238     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
239         ConverterConfig cfg = AudioPolicyManager::GetInstance().GetConverterConfig();
240         converter_ = std::make_unique<AudioSpatialChannelConverter>();
241         if (converter_ == nullptr || !converter_->Init(curStreamParams_, cfg) || !converter_->AllocateMem()) {
242             AUDIO_ERR_LOG("AudioStream: converter construct error");
243             return ERR_NOT_SUPPORTED;
244         }
245         converter_->ConverterChannels(curStreamParams_.channels, curStreamParams_.channelLayout);
246     }
247 
248     if (!IsPlaybackChannelRelatedInfoValid(curStreamParams_.channels, curStreamParams_.channelLayout)) {
249         return ERR_NOT_SUPPORTED;
250     }
251 
252     CHECK_AND_RETURN_RET_LOG(IAudioStream::GetByteSizePerFrame(curStreamParams_, sizePerFrameInByte_) == SUCCESS,
253         ERROR_INVALID_PARAM, "GetByteSizePerFrame failed with invalid params");
254 
255     if (state_ != NEW) {
256         AUDIO_ERR_LOG("State is not new, release existing stream and recreate, state %{public}d", state_.load());
257         int32_t ret = DeinitIpcStream();
258         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "release existing stream failed.");
259     }
260     paramsIsSet_ = true;
261     int32_t initRet = InitIpcStream();
262     CHECK_AND_RETURN_RET_LOG(initRet == SUCCESS, initRet, "Init stream failed: %{public}d", initRet);
263     state_ = PREPARED;
264 
265     // eg: 100005_44100_2_1_client_out.pcm
266     dumpOutFile_ = std::to_string(sessionId_) + "_" + std::to_string(curStreamParams_.samplingRate) + "_" +
267         std::to_string(curStreamParams_.channels) + "_" + std::to_string(curStreamParams_.format) + "_client_out.pcm";
268 
269     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_CLIENT_PARA, dumpOutFile_, &dumpOutFd_);
270     logUtilsTag_ = "[" + std::to_string(sessionId_) + "]NormalRenderer";
271     InitDirectPipeType();
272 
273     proxyObj_ = proxyObj;
274     RegisterTracker(proxyObj);
275     RegisterSpatializationStateEventListener();
276     return SUCCESS;
277 }
278 
GetAudioStreamInfo(AudioStreamParams & info)279 int32_t RendererInClientInner::GetAudioStreamInfo(AudioStreamParams &info)
280 {
281     CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, ERR_OPERATION_FAILED, "Params is not set");
282     info = streamParams_;
283     return SUCCESS;
284 }
285 
GetAudioSessionID(uint32_t & sessionID)286 int32_t RendererInClientInner::GetAudioSessionID(uint32_t &sessionID)
287 {
288     CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != NEW), ERR_ILLEGAL_STATE,
289         "State error %{public}d", state_.load());
290     sessionID = sessionId_;
291     return SUCCESS;
292 }
293 
GetAudioPipeType(AudioPipeType & pipeType)294 void RendererInClientInner::GetAudioPipeType(AudioPipeType &pipeType)
295 {
296     pipeType = rendererInfo_.pipeType;
297 }
298 
GetState()299 State RendererInClientInner::GetState()
300 {
301     std::lock_guard lock(switchingMutex_);
302     if (switchingInfo_.isSwitching_) {
303         AUDIO_INFO_LOG("switching, return state in switchingInfo");
304         return switchingInfo_.state_;
305     }
306     return state_;
307 }
308 
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)309 bool RendererInClientInner::GetAudioTime(Timestamp &timestamp, Timestamp::Timestampbase base)
310 {
311     CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
312     CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
313 
314     uint64_t readPos = 0;
315     int64_t handleTime = 0;
316     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
317     clientBuffer_->GetHandleInfo(readPos, handleTime);
318     if (readPos == 0 || handleTime == 0) {
319         AUDIO_WARNING_LOG("GetHandleInfo may failed");
320     }
321 
322     timestamp.framePosition = readPos;
323     int64_t audioTimeResult = handleTime;
324 
325     if (offloadEnable_) {
326         uint64_t timestampHdi = 0;
327         uint64_t paWriteIndex = 0;
328         uint64_t cacheTimeDsp = 0;
329         uint64_t cacheTimePa = 0;
330         ipcStream_->GetOffloadApproximatelyCacheTime(timestampHdi, paWriteIndex, cacheTimeDsp, cacheTimePa);
331         int64_t cacheTime = static_cast<int64_t>(cacheTimeDsp + cacheTimePa) * AUDIO_NS_PER_US;
332         int64_t timeNow = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
333             std::chrono::system_clock::now().time_since_epoch()).count());
334         int64_t deltaTimeStamp = (static_cast<int64_t>(timeNow) - static_cast<int64_t>(timestampHdi)) * AUDIO_NS_PER_US;
335         uint64_t paWriteIndexNs = paWriteIndex * AUDIO_NS_PER_US;
336         uint64_t readPosNs = readPos * AUDIO_MS_PER_SECOND / curStreamParams_.samplingRate * AUDIO_US_PER_S;
337 
338         int64_t deltaPaWriteIndexNs = static_cast<int64_t>(readPosNs) - static_cast<int64_t>(paWriteIndexNs);
339         int64_t cacheTimeNow = cacheTime - deltaTimeStamp + deltaPaWriteIndexNs;
340         if (offloadStartReadPos_ == 0) {
341             offloadStartReadPos_ = readPosNs;
342             offloadStartHandleTime_ = handleTime;
343         }
344         int64_t offloadDelta = 0;
345         if (offloadStartReadPos_ != 0) {
346             offloadDelta = (static_cast<int64_t>(readPosNs) - static_cast<int64_t>(offloadStartReadPos_)) -
347                            (handleTime - offloadStartHandleTime_) - cacheTimeNow;
348         }
349         audioTimeResult += offloadDelta;
350     }
351 
352     timestamp.time.tv_sec = static_cast<time_t>(audioTimeResult / AUDIO_NS_PER_SECOND);
353     timestamp.time.tv_nsec = static_cast<time_t>(audioTimeResult % AUDIO_NS_PER_SECOND);
354     AUDIO_DEBUG_LOG("audioTimeResult: %{public}" PRIi64, audioTimeResult);
355     return true;
356 }
357 
GetAudioPosition(Timestamp & timestamp,Timestamp::Timestampbase base)358 bool RendererInClientInner::GetAudioPosition(Timestamp &timestamp, Timestamp::Timestampbase base)
359 {
360     CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Renderer stream state is not RUNNING");
361     uint64_t readIdx = 0;
362     uint64_t timestampVal = 0;
363     uint64_t latency = 0;
364     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
365     int32_t ret = ipcStream_->GetAudioPosition(readIdx, timestampVal, latency);
366 
367     uint64_t framePosition = readIdx > lastFlushReadIndex_ ? readIdx - lastFlushReadIndex_ : 0;
368     framePosition = framePosition > latency ? framePosition - latency : 0;
369 
370     // add MCR latency
371     uint32_t mcrLatency = 0;
372     if (converter_ != nullptr) {
373         mcrLatency = converter_->GetLatency() * curStreamParams_.samplingRate / AUDIO_MS_PER_S;
374         framePosition = framePosition > mcrLatency ? framePosition - mcrLatency : 0;
375     }
376 
377     if (lastFramePosition_ < framePosition) {
378         lastFramePosition_ = framePosition;
379         lastFrameTimestamp_ = timestampVal;
380     } else {
381         AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
382         framePosition = lastFramePosition_;
383         timestampVal = lastFrameTimestamp_;
384     }
385     AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
386         ", timestamp %{public}" PRIu64 ", mcrLatency %{public}u, Sinklatency %{public}" PRIu64, framePosition,
387         lastFlushReadIndex_, timestampVal, mcrLatency, latency);
388 
389     timestamp.framePosition = framePosition;
390     timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
391     timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
392     return ret == SUCCESS;
393 }
394 
GetBufferSize(size_t & bufferSize)395 int32_t RendererInClientInner::GetBufferSize(size_t &bufferSize)
396 {
397     CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
398     bufferSize = clientSpanSizeInByte_;
399     if (renderMode_ == RENDER_MODE_CALLBACK) {
400         bufferSize = cbBufferSize_;
401     }
402 
403     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
404         CHECK_AND_RETURN_RET(converter_ != nullptr && converter_->GetInputBufferSize(bufferSize), ERR_OPERATION_FAILED);
405     }
406 
407     AUDIO_INFO_LOG("Buffer size is %{public}zu, mode is %{public}s", bufferSize, renderMode_ == RENDER_MODE_NORMAL ?
408         "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
409     return SUCCESS;
410 }
411 
GetFrameCount(uint32_t & frameCount)412 int32_t RendererInClientInner::GetFrameCount(uint32_t &frameCount)
413 {
414     CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
415     CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, ERR_ILLEGAL_STATE, "sizePerFrameInByte_ is 0!");
416     frameCount = spanSizeInFrame_;
417     if (renderMode_ == RENDER_MODE_CALLBACK) {
418         frameCount = cbBufferSize_ / sizePerFrameInByte_;
419         if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
420             frameCount = frameCount * curStreamParams_.channels / streamParams_.channels;
421         }
422     }
423     AUDIO_INFO_LOG("Frame count is %{public}u, mode is %{public}s", frameCount, renderMode_ == RENDER_MODE_NORMAL ?
424         "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
425     return SUCCESS;
426 }
427 
GetLatency(uint64_t & latency)428 int32_t RendererInClientInner::GetLatency(uint64_t &latency)
429 {
430     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
431     return ipcStream_->GetLatency(latency);
432 }
433 
SetAudioStreamType(AudioStreamType audioStreamType)434 int32_t RendererInClientInner::SetAudioStreamType(AudioStreamType audioStreamType)
435 {
436     AUDIO_ERR_LOG("Change stream type %{public}d to %{public}d is not supported", eStreamType_, audioStreamType);
437     return SUCCESS;
438 }
439 
SetVolume(float volume)440 int32_t RendererInClientInner::SetVolume(float volume)
441 {
442     Trace trace("RendererInClientInner::SetVolume:" + std::to_string(volume));
443     AUDIO_INFO_LOG("[%{public}s]sessionId:%{public}d volume:%{public}f", (offloadEnable_ ? "offload" : "normal"),
444         sessionId_, volume);
445     if (volume < 0.0 || volume > 1.0) {
446         AUDIO_ERR_LOG("SetVolume with invalid volume %{public}f", volume);
447         return ERR_INVALID_PARAM;
448     }
449     if (volumeRamp_.IsActive()) {
450         volumeRamp_.Terminate();
451     }
452     clientVolume_ = volume;
453 
454     return SetInnerVolume(volume);
455 }
456 
GetVolume()457 float RendererInClientInner::GetVolume()
458 {
459     Trace trace("RendererInClientInner::GetVolume:" + std::to_string(clientVolume_));
460     return clientVolume_;
461 }
462 
SetDuckVolume(float volume)463 int32_t RendererInClientInner::SetDuckVolume(float volume)
464 {
465     Trace trace("RendererInClientInner::SetDuckVolume:" + std::to_string(volume));
466     AUDIO_INFO_LOG("sessionId:%{public}d SetDuck:%{public}f", sessionId_, volume);
467     if (volume < 0.0 || volume > 1.0) {
468         AUDIO_ERR_LOG("SetDuckVolume with invalid volume %{public}f", volume);
469         return ERR_INVALID_PARAM;
470     }
471     duckVolume_ = volume;
472     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
473     clientBuffer_->SetDuckFactor(volume);
474     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
475     int32_t ret = ipcStream_->SetDuckFactor(volume);
476     if (ret != SUCCESS) {
477         AUDIO_ERR_LOG("Set Duck failed:%{public}u", ret);
478         return ERROR;
479     }
480     return SUCCESS;
481 }
482 
SetMute(bool mute)483 int32_t RendererInClientInner::SetMute(bool mute)
484 {
485     Trace trace("RendererInClientInner::SetMute:" + std::to_string(mute));
486     AUDIO_INFO_LOG("sessionId:%{public}d SetMute:%{public}d", sessionId_, mute);
487     muteVolume_ = mute ? 0.0f : 1.0f;
488     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
489     clientBuffer_->SetMuteFactor(muteVolume_);
490     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
491     int32_t ret = ipcStream_->SetMute(mute);
492     if (ret != SUCCESS) {
493         AUDIO_ERR_LOG("Set Mute failed:%{public}u", ret);
494         return ERROR;
495     }
496     return SUCCESS;
497 }
498 
SetRenderRate(AudioRendererRate renderRate)499 int32_t RendererInClientInner::SetRenderRate(AudioRendererRate renderRate)
500 {
501     if (rendererRate_ == renderRate) {
502         AUDIO_INFO_LOG("Set same rate");
503         return SUCCESS;
504     }
505     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
506     rendererRate_ = renderRate;
507     return ipcStream_->SetRate(renderRate);
508 }
509 
GetRenderRate()510 AudioRendererRate RendererInClientInner::GetRenderRate()
511 {
512     AUDIO_INFO_LOG("Get RenderRate %{public}d", rendererRate_);
513     return rendererRate_;
514 }
515 
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)516 int32_t RendererInClientInner::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
517 {
518     if (callback == nullptr) {
519         AUDIO_ERR_LOG("SetStreamCallback failed. callback == nullptr");
520         return ERR_INVALID_PARAM;
521     }
522 
523     std::unique_lock<std::mutex> lock(streamCbMutex_);
524     streamCallback_ = callback;
525     lock.unlock();
526 
527     if (state_ != PREPARED) {
528         return SUCCESS;
529     }
530     SafeSendCallbackEvent(STATE_CHANGE_EVENT, PREPARED);
531     return SUCCESS;
532 }
533 
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)534 int32_t RendererInClientInner::SetRendererFirstFrameWritingCallback(
535     const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
536 {
537     AUDIO_INFO_LOG("SetRendererFirstFrameWritingCallback in.");
538     CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "callback is nullptr");
539     std::lock_guard lock(firstFrameWritingMutex_);
540     firstFrameWritingCb_ = callback;
541     return SUCCESS;
542 }
543 
OnFirstFrameWriting()544 void RendererInClientInner::OnFirstFrameWriting()
545 {
546     AUDIO_DEBUG_LOG("In");
547     uint64_t latency = AUDIO_FIRST_FRAME_LATENCY;
548 
549     std::shared_ptr<AudioRendererFirstFrameWritingCallback> cb = nullptr;
550     {
551         std::lock_guard lock(firstFrameWritingMutex_);
552         CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null.");
553         cb = firstFrameWritingCb_;
554     }
555     AUDIO_DEBUG_LOG("OnFirstFrameWriting: latency %{public}" PRIu64 "", latency);
556     cb->OnFirstFrameWriting(latency);
557 }
558 
SetSpeed(float speed)559 int32_t RendererInClientInner::SetSpeed(float speed)
560 {
561     if (audioSpeed_ == nullptr) {
562         audioSpeed_ = std::make_unique<AudioSpeed>(curStreamParams_.samplingRate, curStreamParams_.format,
563             curStreamParams_.channels);
564         GetBufferSize(bufferSize_);
565         speedBuffer_ = std::make_unique<uint8_t[]>(MAX_BUFFER_SIZE);
566     }
567     audioSpeed_->SetSpeed(speed);
568     speed_ = speed;
569     AUDIO_DEBUG_LOG("SetSpeed %{public}f, OffloadEnable %{public}d", speed_, offloadEnable_);
570     return SUCCESS;
571 }
572 
GetSpeed()573 float RendererInClientInner::GetSpeed()
574 {
575     return speed_;
576 }
577 
ChangeSpeed(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)578 int32_t RendererInClientInner::ChangeSpeed(uint8_t *buffer, int32_t bufferSize, std::unique_ptr<uint8_t []> &outBuffer,
579     int32_t &outBufferSize)
580 {
581     return audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, outBuffer, outBufferSize);
582 }
583 
InitCallbackLoop()584 void RendererInClientInner::InitCallbackLoop()
585 {
586     cbThreadReleased_ = false;
587     auto weakRef = weak_from_this();
588     // OS_AudioWriteCB
589     std::thread callbackLoop = std::thread([weakRef] {
590         bool keepRunning = true;
591         std::shared_ptr<RendererInClientInner> strongRef = weakRef.lock();
592         if (strongRef != nullptr) {
593             strongRef->cbThreadCv_.notify_one();
594             AUDIO_INFO_LOG("WriteCallbackFunc start, sessionID :%{public}d", strongRef->sessionId_);
595         } else {
596             AUDIO_WARNING_LOG("Strong ref is nullptr, could cause error");
597         }
598         strongRef = nullptr;
599         // start loop
600         while (keepRunning) {
601             strongRef = weakRef.lock();
602             if (strongRef == nullptr) {
603                 AUDIO_INFO_LOG("RendererInClientInner destroyed");
604                 break;
605             }
606             keepRunning = strongRef->WriteCallbackFunc(); // Main operation in callback loop
607         }
608         if (strongRef != nullptr) {
609             AUDIO_INFO_LOG("CBThread end sessionID :%{public}d", strongRef->sessionId_);
610         }
611     });
612     pthread_setname_np(callbackLoop.native_handle(), "OS_AudioWriteCB");
613     callbackLoop.detach();
614 }
615 
SetRenderMode(AudioRenderMode renderMode)616 int32_t RendererInClientInner::SetRenderMode(AudioRenderMode renderMode)
617 {
618     AUDIO_INFO_LOG("SetRenderMode to %{public}s", renderMode == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
619         "RENDER_MODE_CALLBACK");
620     if (renderMode_ == renderMode) {
621         return SUCCESS;
622     }
623 
624     // renderMode_ is inited as RENDER_MODE_NORMAL, can only be set to RENDER_MODE_CALLBACK.
625     if (renderMode_ == RENDER_MODE_CALLBACK && renderMode == RENDER_MODE_NORMAL) {
626         AUDIO_ERR_LOG("SetRenderMode from callback to normal is not supported.");
627         return ERR_INCORRECT_MODE;
628     }
629 
630     // state check
631     if (state_ != PREPARED && state_ != NEW) {
632         AUDIO_ERR_LOG("SetRenderMode failed. invalid state:%{public}d", state_.load());
633         return ERR_ILLEGAL_STATE;
634     }
635     renderMode_ = renderMode;
636 
637     // init callbackLoop_
638     InitCallbackLoop();
639 
640     std::unique_lock<std::mutex> threadStartlock(statusMutex_);
641     bool stopWaiting = cbThreadCv_.wait_for(threadStartlock, std::chrono::milliseconds(SHORT_TIMEOUT_IN_MS), [this] {
642         return cbThreadReleased_ == false; // When thread is started, cbThreadReleased_ will be false. So stop waiting.
643     });
644     if (!stopWaiting) {
645         AUDIO_WARNING_LOG("Init OS_AudioWriteCB thread time out");
646     }
647 
648     InitCallbackBuffer(OLD_BUF_DURATION_IN_USEC);
649     return SUCCESS;
650 }
651 
GetRenderMode()652 AudioRenderMode RendererInClientInner::GetRenderMode()
653 {
654     AUDIO_INFO_LOG("Render mode is %{public}s", renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
655         "RENDER_MODE_CALLBACK");
656     return renderMode_;
657 }
658 
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)659 int32_t RendererInClientInner::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
660 {
661     CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "Invalid null callback");
662     CHECK_AND_RETURN_RET_LOG(renderMode_ == RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE, "incorrect render mode");
663     std::lock_guard<std::mutex> lock(writeCbMutex_);
664     writeCb_ = callback;
665     return SUCCESS;
666 }
667 
SetCaptureMode(AudioCaptureMode captureMode)668 int32_t RendererInClientInner::SetCaptureMode(AudioCaptureMode captureMode)
669 {
670     AUDIO_ERR_LOG("SetCaptureMode is not supported");
671     return ERROR;
672 }
673 
GetCaptureMode()674 AudioCaptureMode RendererInClientInner::GetCaptureMode()
675 {
676     AUDIO_ERR_LOG("GetCaptureMode is not supported");
677     return CAPTURE_MODE_NORMAL; // not supported
678 }
679 
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)680 int32_t RendererInClientInner::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
681 {
682     AUDIO_ERR_LOG("SetCapturerReadCallback is not supported");
683     return ERROR;
684 }
685 
GetBufferDesc(BufferDesc & bufDesc)686 int32_t RendererInClientInner::GetBufferDesc(BufferDesc &bufDesc)
687 {
688     Trace trace("RendererInClientInner::GetBufferDesc");
689     if (renderMode_ != RENDER_MODE_CALLBACK) {
690         AUDIO_ERR_LOG("GetBufferDesc is not supported. Render mode is not callback.");
691         return ERR_INCORRECT_MODE;
692     }
693     std::lock_guard<std::mutex> lock(cbBufferMutex_);
694     bufDesc.buffer = cbBuffer_.get();
695     bufDesc.bufLength = cbBufferSize_;
696     bufDesc.dataLength = cbBufferSize_;
697     if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
698         CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_INVALID_OPERATION, "converter is not inited");
699         bufDesc.metaBuffer = bufDesc.buffer + cbBufferSize_;
700         bufDesc.metaLength = converter_->GetMetaSize();
701     }
702     return SUCCESS;
703 }
704 
GetBufQueueState(BufferQueueState & bufState)705 int32_t RendererInClientInner::GetBufQueueState(BufferQueueState &bufState)
706 {
707     Trace trace("RendererInClientInner::GetBufQueueState");
708     if (renderMode_ != RENDER_MODE_CALLBACK) {
709         AUDIO_ERR_LOG("GetBufQueueState is not supported. Render mode is not callback.");
710         return ERR_INCORRECT_MODE;
711     }
712     // only one buffer in queue.
713     bufState.numBuffers = 1;
714     bufState.currentIndex = 0;
715     return SUCCESS;
716 }
717 
Enqueue(const BufferDesc & bufDesc)718 int32_t RendererInClientInner::Enqueue(const BufferDesc &bufDesc)
719 {
720     Trace trace("RendererInClientInner::Enqueue " + std::to_string(bufDesc.bufLength));
721     if (renderMode_ != RENDER_MODE_CALLBACK) {
722         AUDIO_ERR_LOG("Enqueue is not supported. Render mode is not callback.");
723         return ERR_INCORRECT_MODE;
724     }
725     CHECK_AND_RETURN_RET_LOG(bufDesc.buffer != nullptr && bufDesc.bufLength != 0, ERR_INVALID_PARAM, "Invalid buffer");
726     CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID ||
727             converter_ != nullptr && converter_->CheckInputValid(bufDesc),
728         ERR_INVALID_PARAM, "Invalid buffer desc");
729     if (bufDesc.bufLength > cbBufferSize_ || bufDesc.dataLength > cbBufferSize_) {
730         AUDIO_WARNING_LOG("Invalid bufLength:%{public}zu or dataLength:%{public}zu, should be %{public}zu",
731             bufDesc.bufLength, bufDesc.dataLength, cbBufferSize_);
732     }
733 
734     BufferDesc temp = bufDesc;
735 
736     if (state_ == RELEASED) {
737         AUDIO_WARNING_LOG("Invalid state: %{public}d", state_.load());
738         return ERR_ILLEGAL_STATE;
739     }
740     // Call write here may block, so put it in loop callbackLoop_
741     cbBufferQueue_.Push(temp);
742     return SUCCESS;
743 }
744 
Clear()745 int32_t RendererInClientInner::Clear()
746 {
747     Trace trace("RendererInClientInner::Clear");
748     if (renderMode_ != RENDER_MODE_CALLBACK) {
749         AUDIO_ERR_LOG("Clear is not supported. Render mode is not callback.");
750         return ERR_INCORRECT_MODE;
751     }
752     std::unique_lock<std::mutex> lock(cbBufferMutex_);
753     int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
754     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
755     lock.unlock();
756     FlushAudioStream();
757     return SUCCESS;
758 }
759 
SetLowPowerVolume(float volume)760 int32_t RendererInClientInner::SetLowPowerVolume(float volume)
761 {
762     AUDIO_INFO_LOG("Volume number: %{public}f", volume);
763     if (volume < 0.0 || volume > 1.0) {
764         AUDIO_ERR_LOG("Invalid param: %{public}f", volume);
765         return ERR_INVALID_PARAM;
766     }
767     lowPowerVolume_ = volume;
768 
769     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
770     return ipcStream_->SetLowPowerVolume(lowPowerVolume_);
771 }
772 
GetLowPowerVolume()773 float RendererInClientInner::GetLowPowerVolume()
774 {
775     return lowPowerVolume_;
776 }
777 
SetOffloadMode(int32_t state,bool isAppBack)778 int32_t RendererInClientInner::SetOffloadMode(int32_t state, bool isAppBack)
779 {
780     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
781     return ipcStream_->SetOffloadMode(state, isAppBack);
782 }
783 
UnsetOffloadMode()784 int32_t RendererInClientInner::UnsetOffloadMode()
785 {
786     rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
787     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
788     return ipcStream_->UnsetOffloadMode();
789 }
790 
GetSingleStreamVolume()791 float RendererInClientInner::GetSingleStreamVolume()
792 {
793     // in plan. For now, keep it consistent with fast_audio_stream
794     return 1.0f;
795 }
796 
GetAudioEffectMode()797 AudioEffectMode RendererInClientInner::GetAudioEffectMode()
798 {
799     AUDIO_DEBUG_LOG("Current audio effect mode is %{public}d", effectMode_);
800     return effectMode_;
801 }
802 
SetAudioEffectMode(AudioEffectMode effectMode)803 int32_t RendererInClientInner::SetAudioEffectMode(AudioEffectMode effectMode)
804 {
805     if (effectMode_ == effectMode) {
806         AUDIO_INFO_LOG("Set same effect mode");
807         return SUCCESS;
808     }
809 
810     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
811     int32_t ret = ipcStream_->SetAudioEffectMode(effectMode);
812     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Set audio effect mode failed");
813     effectMode_ = effectMode;
814     return SUCCESS;
815 }
816 
GetFramesWritten()817 int64_t RendererInClientInner::GetFramesWritten()
818 {
819     return totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
820 }
821 
GetFramesRead()822 int64_t RendererInClientInner::GetFramesRead()
823 {
824     AUDIO_ERR_LOG("not supported");
825     return -1;
826 }
827 
SetInnerCapturerState(bool isInnerCapturer)828 void RendererInClientInner::SetInnerCapturerState(bool isInnerCapturer)
829 {
830     AUDIO_ERR_LOG("SetInnerCapturerState is not supported");
831     return;
832 }
833 
SetWakeupCapturerState(bool isWakeupCapturer)834 void RendererInClientInner::SetWakeupCapturerState(bool isWakeupCapturer)
835 {
836     AUDIO_ERR_LOG("SetWakeupCapturerState is not supported");
837     return;
838 }
839 
SetCapturerSource(int capturerSource)840 void RendererInClientInner::SetCapturerSource(int capturerSource)
841 {
842     AUDIO_ERR_LOG("SetCapturerSource is not supported");
843     return;
844 }
845 
SetPrivacyType(AudioPrivacyType privacyType)846 void RendererInClientInner::SetPrivacyType(AudioPrivacyType privacyType)
847 {
848     if (privacyType_ == privacyType) {
849         AUDIO_INFO_LOG("Set same privacy type");
850         return;
851     }
852     privacyType_ = privacyType;
853     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
854     int32_t ret = ipcStream_->SetPrivacyType(privacyType);
855     CHECK_AND_RETURN_LOG(ret == SUCCESS, "Set privacy type failed");
856 }
857 
StartAudioStream(StateChangeCmdType cmdType,AudioStreamDeviceChangeReasonExt reason)858 bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType,
859     AudioStreamDeviceChangeReasonExt reason)
860 {
861     Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_));
862     std::unique_lock<std::mutex> statusLock(statusMutex_);
863     if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) {
864         AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load());
865         return false;
866     }
867 
868     hasFirstFrameWrited_ = false;
869     if (audioStreamTracker_ && audioStreamTracker_.get()) {
870         audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_, RUNNING, clientPid_, rendererInfo_, reason);
871     }
872     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
873     int32_t ret = ipcStream_->Start();
874     if (ret != SUCCESS) {
875         AUDIO_ERR_LOG("Start call server failed:%{public}u", ret);
876         return false;
877     }
878     std::unique_lock<std::mutex> waitLock(callServerMutex_);
879     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
880         return state_ == RUNNING; // will be false when got notified.
881     });
882     if (!stopWaiting) {
883         AUDIO_ERR_LOG("Start failed: timeout");
884         ipcStream_->Stop();
885         return false;
886     }
887 
888     waitLock.unlock();
889 
890     AUDIO_INFO_LOG("Start SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
891     UpdateTracker("RUNNING");
892 
893     std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
894     if (!isDataLinkConnected_) {
895         AUDIO_INFO_LOG("data-connection blocking starts.");
896         stopWaiting = dataConnectionCV_.wait_for(
897             dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
898                 return isDataLinkConnected_;
899             });
900         AUDIO_INFO_LOG("data-connection blocking ends.");
901     }
902     dataConnectionWaitLock.unlock();
903 
904     offloadStartReadPos_ = 0;
905     if (renderMode_ == RENDER_MODE_CALLBACK) {
906         // start the callback-write thread
907         cbThreadCv_.notify_all();
908     }
909     statusLock.unlock();
910     // in plan: call HiSysEventWrite
911     int64_t param = -1;
912     StateCmdTypeToParams(param, state_, cmdType);
913     SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
914     preWriteEndTime_ = 0;
915     return true;
916 }
917 
PauseAudioStream(StateChangeCmdType cmdType)918 bool RendererInClientInner::PauseAudioStream(StateChangeCmdType cmdType)
919 {
920     Trace trace("RendererInClientInner::PauseAudioStream " + std::to_string(sessionId_));
921     std::unique_lock<std::mutex> statusLock(statusMutex_);
922     if (state_ != RUNNING) {
923         AUDIO_ERR_LOG("State is not RUNNING. Illegal state:%{public}u", state_.load());
924         return false;
925     }
926 
927     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
928     int32_t ret = ipcStream_->Pause();
929     if (ret != SUCCESS) {
930         AUDIO_ERR_LOG("call server failed:%{public}u", ret);
931         return false;
932     }
933     std::unique_lock<std::mutex> waitLock(callServerMutex_);
934     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
935         return state_ == PAUSED; // will be false when got notified.
936     });
937     if (!stopWaiting) {
938         AUDIO_ERR_LOG("Pause failed: timeout");
939         return false;
940     }
941 
942     waitLock.unlock();
943 
944     FutexTool::FutexWake(clientBuffer_->GetFutex());
945     statusLock.unlock();
946 
947     // in plan: call HiSysEventWrite
948     int64_t param = -1;
949     StateCmdTypeToParams(param, state_, cmdType);
950     SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
951 
952     AUDIO_INFO_LOG("Pause SUCCESS, sessionId %{public}d, uid %{public}d, mode %{public}s", sessionId_,
953         clientUid_, renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
954     UpdateTracker("PAUSED");
955     return true;
956 }
957 
StopAudioStream()958 bool RendererInClientInner::StopAudioStream()
959 {
960     Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_));
961     AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
962     std::unique_lock<std::mutex> statusLock(statusMutex_);
963     std::unique_lock<std::mutex> lock(writeMutex_, std::defer_lock);
964     if (!offloadEnable_) {
965         lock.lock();
966         DrainAudioStreamInner(true);
967     }
968 
969     if (state_ == STOPPED) {
970         AUDIO_INFO_LOG("Renderer in client is already stopped");
971         return true;
972     }
973     if ((state_ != RUNNING) && (state_ != PAUSED)) {
974         AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load());
975         return false;
976     }
977 
978     std::unique_lock<std::mutex> waitLock(callServerMutex_);
979     if (renderMode_ == RENDER_MODE_CALLBACK) {
980         state_ = STOPPING;
981         AUDIO_INFO_LOG("Stop begin in callback mode sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
982     }
983 
984     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
985     int32_t ret = ipcStream_->Stop();
986     if (ret != SUCCESS) {
987         AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret);
988         return false;
989     }
990 
991     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
992         return state_ == STOPPED; // will be false when got notified.
993     });
994     if (!stopWaiting) {
995         AUDIO_ERR_LOG("Stop failed: timeout");
996         state_ = INVALID;
997         return false;
998     }
999 
1000     waitLock.unlock();
1001 
1002     FutexTool::FutexWake(clientBuffer_->GetFutex());
1003     statusLock.unlock();
1004 
1005     // in plan: call HiSysEventWrite
1006     SafeSendCallbackEvent(STATE_CHANGE_EVENT, state_);
1007 
1008     AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1009     UpdateTracker("STOPPED");
1010     return true;
1011 }
1012 
ReleaseAudioStream(bool releaseRunner,bool isSwitchStream)1013 bool RendererInClientInner::ReleaseAudioStream(bool releaseRunner, bool isSwitchStream)
1014 {
1015     (void)isSwitchStream;
1016     AUDIO_PRERELEASE_LOGI("Enter");
1017     std::unique_lock<std::mutex> statusLock(statusMutex_);
1018     if (state_ == RELEASED) {
1019         AUDIO_WARNING_LOG("Already released, do nothing");
1020         return true;
1021     }
1022     state_ = RELEASED;
1023     statusLock.unlock();
1024 
1025     Trace trace("RendererInClientInner::ReleaseAudioStream " + std::to_string(sessionId_));
1026     if (ipcStream_ != nullptr) {
1027         ipcStream_->Release();
1028     } else {
1029         AUDIO_WARNING_LOG("release while ipcStream is null");
1030     }
1031 
1032     // no lock, call release in any case, include blocked case.
1033     std::unique_lock<std::mutex> runnerlock(runnerMutex_);
1034     if (releaseRunner && callbackHandler_ != nullptr) {
1035         callbackHandler_->ReleaseEventRunner();
1036         runnerReleased_ = true;
1037         callbackHandler_ = nullptr;
1038     }
1039     runnerlock.unlock();
1040 
1041     // clear write callback
1042     if (renderMode_ == RENDER_MODE_CALLBACK) {
1043         cbThreadReleased_ = true; // stop loop
1044         cbThreadCv_.notify_all();
1045         FutexTool::FutexWake(clientBuffer_->GetFutex(), IS_PRE_EXIT);
1046     }
1047     paramsIsSet_ = false;
1048 
1049     std::unique_lock<std::mutex> lock(streamCbMutex_);
1050     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1051     if (streamCb != nullptr) {
1052         AUDIO_INFO_LOG("Notify client the state is released");
1053         streamCb->OnStateChange(RELEASED, CMD_FROM_CLIENT);
1054     }
1055     lock.unlock();
1056 
1057     UpdateTracker("RELEASED");
1058     AUDIO_INFO_LOG("Release end, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1059 
1060     audioSpeed_.reset();
1061     audioSpeed_ = nullptr;
1062     return true;
1063 }
1064 
FlushAudioStream()1065 bool RendererInClientInner::FlushAudioStream()
1066 {
1067     Trace trace("RendererInClientInner::FlushAudioStream " + std::to_string(sessionId_));
1068     std::unique_lock<std::mutex> statusLock(statusMutex_);
1069     std::lock_guard<std::mutex>lock(writeMutex_);
1070     if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
1071         AUDIO_ERR_LOG("Flush failed. Illegal state:%{public}u", state_.load());
1072         return false;
1073     }
1074 
1075     // clear cbBufferQueue
1076     if (renderMode_ == RENDER_MODE_CALLBACK) {
1077         cbBufferQueue_.Clear();
1078         int chToFill = (clientConfig_.streamInfo.format == SAMPLE_U8) ? 0x7f : 0;
1079         if (memset_s(cbBuffer_.get(), cbBufferSize_, chToFill, cbBufferSize_) != EOK) {
1080             AUDIO_ERR_LOG("memset_s buffer failed");
1081         }
1082     }
1083 
1084     CHECK_AND_RETURN_RET_LOG(FlushRingCache() == SUCCESS, false, "Flush cache failed");
1085 
1086     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1087     int32_t ret = ipcStream_->Flush();
1088     if (ret != SUCCESS) {
1089         AUDIO_ERR_LOG("Flush call server failed:%{public}u", ret);
1090         return false;
1091     }
1092 
1093     // clear multichannel render buffer
1094     if (converter_) {
1095         ret = converter_->Flush();
1096         if (ret != SUCCESS) {
1097             AUDIO_ERR_LOG("Flush mcr buffer failed.");
1098         }
1099     }
1100     std::unique_lock<std::mutex> waitLock(callServerMutex_);
1101     bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1102         return notifiedOperation_ == FLUSH_STREAM; // will be false when got notified.
1103     });
1104 
1105     if (notifiedOperation_ != FLUSH_STREAM || notifiedResult_ != SUCCESS) {
1106         AUDIO_ERR_LOG("Flush failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1107             (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1108         notifiedOperation_ = MAX_OPERATION_CODE;
1109         return false;
1110     }
1111     notifiedOperation_ = MAX_OPERATION_CODE;
1112     waitLock.unlock();
1113     ResetFramePosition();
1114     AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
1115     return true;
1116 }
1117 
DrainAudioStream(bool stopFlag)1118 bool RendererInClientInner::DrainAudioStream(bool stopFlag)
1119 {
1120     std::lock_guard<std::mutex> statusLock(statusMutex_);
1121     std::lock_guard<std::mutex> lock(writeMutex_);
1122     bool ret = DrainAudioStreamInner(stopFlag);
1123     return ret;
1124 }
1125 
Write(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1126 int32_t RendererInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1127     size_t metaBufferSize)
1128 {
1129     CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1130         "Write with callback is not supported");
1131     int32_t ret = WriteInner(pcmBuffer, pcmBufferSize, metaBuffer, metaBufferSize);
1132     return ret <= 0 ? ret : static_cast<int32_t>(pcmBufferSize);
1133 }
1134 
Write(uint8_t * buffer,size_t bufferSize)1135 int32_t RendererInClientInner::Write(uint8_t *buffer, size_t bufferSize)
1136 {
1137     CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1138         "Write with callback is not supported");
1139     return WriteInner(buffer, bufferSize);
1140 }
1141 
SetPreferredFrameSize(int32_t frameSize)1142 void RendererInClientInner::SetPreferredFrameSize(int32_t frameSize)
1143 {
1144     std::lock_guard<std::mutex> lockSetPreferredFrameSize(setPreferredFrameSizeMutex_);
1145     userSettedPreferredFrameSize_ = frameSize;
1146     CHECK_AND_RETURN_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID,
1147         "playing audiovivid, frameSize is always 1024.");
1148     size_t maxCbBufferSize =
1149         static_cast<size_t>(MAX_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1150     size_t minCbBufferSize =
1151         static_cast<size_t>(MIN_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1152     size_t preferredCbBufferSize = static_cast<size_t>(frameSize) * sizePerFrameInByte_;
1153     std::lock_guard<std::mutex> lock(cbBufferMutex_);
1154     cbBufferSize_ = (preferredCbBufferSize > maxCbBufferSize || preferredCbBufferSize < minCbBufferSize) ?
1155         (preferredCbBufferSize > maxCbBufferSize ? maxCbBufferSize : minCbBufferSize) : preferredCbBufferSize;
1156     AUDIO_INFO_LOG("Set CallbackBuffer with byte size: %{public}zu", cbBufferSize_);
1157     cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_);
1158     return;
1159 }
1160 
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)1161 int32_t RendererInClientInner::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
1162 {
1163     AUDIO_ERR_LOG("Read is not supported");
1164     return ERROR;
1165 }
1166 
GetUnderflowCount()1167 uint32_t RendererInClientInner::GetUnderflowCount()
1168 {
1169     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, 0, "buffer is not inited");
1170 
1171     return clientBuffer_->GetUnderrunCount();
1172 }
1173 
GetOverflowCount()1174 uint32_t RendererInClientInner::GetOverflowCount()
1175 {
1176     AUDIO_WARNING_LOG("No Overflow in renderer");
1177     return 0;
1178 }
1179 
SetUnderflowCount(uint32_t underflowCount)1180 void RendererInClientInner::SetUnderflowCount(uint32_t underflowCount)
1181 {
1182     CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "buffer is not inited");
1183     clientBuffer_->SetUnderrunCount(underflowCount);
1184 }
1185 
SetOverflowCount(uint32_t overflowCount)1186 void RendererInClientInner::SetOverflowCount(uint32_t overflowCount)
1187 {
1188     // not support for renderer
1189     AUDIO_WARNING_LOG("No Overflow in renderer");
1190     return;
1191 }
1192 
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1193 void RendererInClientInner::SetRendererPositionCallback(int64_t markPosition,
1194     const std::shared_ptr<RendererPositionCallback> &callback)
1195 {
1196     // waiting for review
1197     std::lock_guard<std::mutex> lock(markReachMutex_);
1198     CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPositionCallback is nullptr");
1199     rendererPositionCallback_ = callback;
1200     rendererMarkPosition_ = markPosition;
1201     rendererMarkReached_ = false;
1202 }
1203 
UnsetRendererPositionCallback()1204 void RendererInClientInner::UnsetRendererPositionCallback()
1205 {
1206     // waiting for review
1207     std::lock_guard<std::mutex> lock(markReachMutex_);
1208     rendererPositionCallback_ = nullptr;
1209     rendererMarkPosition_ = 0;
1210     rendererMarkReached_ = false;
1211 }
1212 
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)1213 void RendererInClientInner::SetRendererPeriodPositionCallback(int64_t periodPosition,
1214     const std::shared_ptr<RendererPeriodPositionCallback> &callback)
1215 {
1216     // waiting for review
1217     std::lock_guard<std::mutex> lock(periodReachMutex_);
1218     CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPeriodPositionCallback is nullptr");
1219     rendererPeriodPositionCallback_ = callback;
1220     rendererPeriodSize_ = periodPosition;
1221     totalBytesWritten_ = 0;
1222     rendererPeriodWritten_ = 0;
1223 }
1224 
UnsetRendererPeriodPositionCallback()1225 void RendererInClientInner::UnsetRendererPeriodPositionCallback()
1226 {
1227     // waiting for review
1228     std::lock_guard<std::mutex> lock(periodReachMutex_);
1229     rendererPeriodPositionCallback_ = nullptr;
1230     rendererPeriodSize_ = 0;
1231     totalBytesWritten_ = 0;
1232     rendererPeriodWritten_ = 0;
1233 }
1234 
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)1235 void RendererInClientInner::SetCapturerPositionCallback(int64_t markPosition,
1236     const std::shared_ptr<CapturerPositionCallback> &callback)
1237 {
1238     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1239     return;
1240 }
1241 
UnsetCapturerPositionCallback()1242 void RendererInClientInner::UnsetCapturerPositionCallback()
1243 {
1244     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1245     return;
1246 }
1247 
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)1248 void RendererInClientInner::SetCapturerPeriodPositionCallback(int64_t periodPosition,
1249     const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
1250 {
1251     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1252     return;
1253 }
1254 
UnsetCapturerPeriodPositionCallback()1255 void RendererInClientInner::UnsetCapturerPeriodPositionCallback()
1256 {
1257     AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
1258     return;
1259 }
1260 
SetRendererSamplingRate(uint32_t sampleRate)1261 int32_t RendererInClientInner::SetRendererSamplingRate(uint32_t sampleRate)
1262 {
1263     AUDIO_ERR_LOG("SetRendererSamplingRate to %{public}d is not supported", sampleRate);
1264     return ERROR;
1265 }
1266 
GetRendererSamplingRate()1267 uint32_t RendererInClientInner::GetRendererSamplingRate()
1268 {
1269     return curStreamParams_.samplingRate;
1270 }
1271 
SetBufferSizeInMsec(int32_t bufferSizeInMsec)1272 int32_t RendererInClientInner::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
1273 {
1274     // bufferSizeInMsec is checked between 5ms and 20ms.
1275     bufferSizeInMsec_ = static_cast<uint32_t>(bufferSizeInMsec);
1276     AUDIO_INFO_LOG("SetBufferSizeInMsec to %{public}d", bufferSizeInMsec_);
1277     if (renderMode_ == RENDER_MODE_CALLBACK) {
1278         uint64_t bufferDurationInUs = bufferSizeInMsec_ * AUDIO_US_PER_MS;
1279         InitCallbackBuffer(bufferDurationInUs);
1280     }
1281     return SUCCESS;
1282 }
1283 
SetChannelBlendMode(ChannelBlendMode blendMode)1284 int32_t RendererInClientInner::SetChannelBlendMode(ChannelBlendMode blendMode)
1285 {
1286     if ((state_ != PREPARED) && (state_ != NEW)) {
1287         AUDIO_ERR_LOG("SetChannelBlendMode in invalid status:%{public}d", state_.load());
1288         return ERR_ILLEGAL_STATE;
1289     }
1290     isBlendSet_ = true;
1291     audioBlend_.SetParams(blendMode, curStreamParams_.format, curStreamParams_.channels);
1292     return SUCCESS;
1293 }
1294 
SetVolumeWithRamp(float volume,int32_t duration)1295 int32_t RendererInClientInner::SetVolumeWithRamp(float volume, int32_t duration)
1296 {
1297     CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != INVALID) && (state_ != STOPPED),
1298         ERR_ILLEGAL_STATE, "Illegal state %{public}d", state_.load());
1299 
1300     if (FLOAT_COMPARE_EQ(clientVolume_, volume)) {
1301         AUDIO_INFO_LOG("set same volume %{public}f", volume);
1302         return SUCCESS;
1303     }
1304 
1305     volumeRamp_.SetVolumeRampConfig(volume, clientVolume_, duration);
1306     return SUCCESS;
1307 }
1308 
SetStreamTrackerState(bool trackerRegisteredState)1309 void RendererInClientInner::SetStreamTrackerState(bool trackerRegisteredState)
1310 {
1311     streamTrackerRegistered_ = trackerRegisteredState;
1312 }
1313 
GetSwitchInfo(IAudioStream::SwitchInfo & info)1314 void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info)
1315 {
1316     info.params = streamParams_;
1317 
1318     info.rendererInfo = rendererInfo_;
1319     info.capturerInfo = capturerInfo_;
1320     info.eStreamType = eStreamType_;
1321     info.renderMode = renderMode_;
1322     info.state = state_;
1323     info.sessionId = sessionId_;
1324     info.streamTrackerRegistered = streamTrackerRegistered_;
1325     info.defaultOutputDevice = defaultOutputDevice_;
1326     GetStreamSwitchInfo(info);
1327 
1328     {
1329         std::lock_guard<std::mutex> lock(setPreferredFrameSizeMutex_);
1330         info.userSettedPreferredFrameSize = userSettedPreferredFrameSize_;
1331     }
1332 }
1333 
GetStreamSwitchInfo(IAudioStream::SwitchInfo & info)1334 void RendererInClientInner::GetStreamSwitchInfo(IAudioStream::SwitchInfo& info)
1335 {
1336     info.underFlowCount = GetUnderflowCount();
1337     info.effectMode = effectMode_;
1338     info.renderRate = rendererRate_;
1339     info.clientPid = clientPid_;
1340     info.clientUid = clientUid_;
1341     info.volume = clientVolume_;
1342     info.silentModeAndMixWithOthers = silentModeAndMixWithOthers_;
1343 
1344     info.frameMarkPosition = static_cast<uint64_t>(rendererMarkPosition_);
1345     info.renderPositionCb = rendererPositionCallback_;
1346 
1347     info.framePeriodNumber = static_cast<uint64_t>(rendererPeriodSize_);
1348     info.renderPeriodPositionCb = rendererPeriodPositionCallback_;
1349 
1350     info.rendererWriteCallback = writeCb_;
1351 }
1352 
GetStreamClass()1353 IAudioStream::StreamClass RendererInClientInner::GetStreamClass()
1354 {
1355     return PA_STREAM;
1356 }
1357 
OnHandle(uint32_t code,int64_t data)1358 void RendererInClientInner::OnHandle(uint32_t code, int64_t data)
1359 {
1360     AUDIO_DEBUG_LOG("On handle event, event code: %{public}d, data: %{public}" PRIu64 "", code, data);
1361     switch (code) {
1362         case STATE_CHANGE_EVENT:
1363             HandleStateChangeEvent(data);
1364             break;
1365         case RENDERER_MARK_REACHED_EVENT:
1366             HandleRenderMarkReachedEvent(data);
1367             break;
1368         case RENDERER_PERIOD_REACHED_EVENT:
1369             HandleRenderPeriodReachedEvent(data);
1370             break;
1371         default:
1372             break;
1373     }
1374 }
1375 
InitCallbackHandler()1376 void RendererInClientInner::InitCallbackHandler()
1377 {
1378     std::lock_guard<std::mutex> lock(runnerMutex_);
1379     if (callbackHandler_ == nullptr) {
1380         callbackHandler_ = CallbackHandler::GetInstance(shared_from_this(), "OS_AudioStateCB");
1381     }
1382 }
1383 
SafeSendCallbackEvent(uint32_t eventCode,int64_t data)1384 void RendererInClientInner::SafeSendCallbackEvent(uint32_t eventCode, int64_t data)
1385 {
1386     std::lock_guard<std::mutex> lock(runnerMutex_);
1387     AUDIO_INFO_LOG("Send callback event, code: %{public}u, data: %{public}" PRId64 "", eventCode, data);
1388     CHECK_AND_RETURN_LOG(callbackHandler_ != nullptr && runnerReleased_ == false, "Runner is Released");
1389     callbackHandler_->SendCallbackEvent(eventCode, data);
1390 }
1391 
StateCmdTypeToParams(int64_t & params,State state,StateChangeCmdType cmdType)1392 int32_t RendererInClientInner::StateCmdTypeToParams(int64_t &params, State state, StateChangeCmdType cmdType)
1393 {
1394     if (cmdType == CMD_FROM_CLIENT) {
1395         params = static_cast<int64_t>(state);
1396         return SUCCESS;
1397     }
1398     switch (state) {
1399         case RUNNING:
1400             params = HANDLER_PARAM_RUNNING_FROM_SYSTEM;
1401             break;
1402         case PAUSED:
1403             params = HANDLER_PARAM_PAUSED_FROM_SYSTEM;
1404             break;
1405         default:
1406             params = HANDLER_PARAM_INVALID;
1407             break;
1408     }
1409     return SUCCESS;
1410 }
1411 
ParamsToStateCmdType(int64_t params,State & state,StateChangeCmdType & cmdType)1412 int32_t RendererInClientInner::ParamsToStateCmdType(int64_t params, State &state, StateChangeCmdType &cmdType)
1413 {
1414     cmdType = CMD_FROM_CLIENT;
1415     switch (params) {
1416         case HANDLER_PARAM_NEW:
1417             state = NEW;
1418             break;
1419         case HANDLER_PARAM_PREPARED:
1420             state = PREPARED;
1421             break;
1422         case HANDLER_PARAM_RUNNING:
1423             state = RUNNING;
1424             break;
1425         case HANDLER_PARAM_STOPPED:
1426             state = STOPPED;
1427             break;
1428         case HANDLER_PARAM_RELEASED:
1429             state = RELEASED;
1430             break;
1431         case HANDLER_PARAM_PAUSED:
1432             state = PAUSED;
1433             break;
1434         case HANDLER_PARAM_STOPPING:
1435             state = STOPPING;
1436             break;
1437         case HANDLER_PARAM_RUNNING_FROM_SYSTEM:
1438             state = RUNNING;
1439             cmdType = CMD_FROM_SYSTEM;
1440             break;
1441         case HANDLER_PARAM_PAUSED_FROM_SYSTEM:
1442             state = PAUSED;
1443             cmdType = CMD_FROM_SYSTEM;
1444             break;
1445         default:
1446             state = INVALID;
1447             break;
1448     }
1449     return SUCCESS;
1450 }
1451 
1452 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedEvent(int64_t rendererMarkPosition)1453 void RendererInClientInner::SendRenderMarkReachedEvent(int64_t rendererMarkPosition)
1454 {
1455     SafeSendCallbackEvent(RENDERER_MARK_REACHED_EVENT, rendererMarkPosition);
1456 }
1457 
1458 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)1459 void RendererInClientInner::SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)
1460 {
1461     SafeSendCallbackEvent(RENDERER_PERIOD_REACHED_EVENT, rendererPeriodSize);
1462 }
1463 
HandleRendererPositionChanges(size_t bytesWritten)1464 void RendererInClientInner::HandleRendererPositionChanges(size_t bytesWritten)
1465 {
1466     totalBytesWritten_ += static_cast<int64_t>(bytesWritten);
1467     if (sizePerFrameInByte_ == 0) {
1468         AUDIO_ERR_LOG("HandleRendererPositionChanges: sizePerFrameInByte_ is 0");
1469         return;
1470     }
1471     int64_t writtenFrameNumber = totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1472     AUDIO_DEBUG_LOG("frame size: %{public}zu", sizePerFrameInByte_);
1473 
1474     {
1475         std::lock_guard<std::mutex> lock(markReachMutex_);
1476         if (!rendererMarkReached_) {
1477             AUDIO_DEBUG_LOG("Frame mark position: %{public}" PRId64", Total frames written: %{public}" PRId64,
1478                 static_cast<int64_t>(rendererMarkPosition_), static_cast<int64_t>(writtenFrameNumber));
1479             if (writtenFrameNumber >= rendererMarkPosition_) {
1480                 AUDIO_DEBUG_LOG("OnMarkReached %{public}" PRId64".", rendererMarkPosition_);
1481                 SendRenderMarkReachedEvent(rendererMarkPosition_);
1482                 rendererMarkReached_ = true;
1483             }
1484         }
1485     }
1486 
1487     {
1488         std::lock_guard<std::mutex> lock(periodReachMutex_);
1489         rendererPeriodWritten_ += static_cast<int64_t>((bytesWritten / sizePerFrameInByte_));
1490         AUDIO_DEBUG_LOG("Frame period number: %{public}" PRId64", Total frames written: %{public}" PRId64,
1491             static_cast<int64_t>(rendererPeriodWritten_), static_cast<int64_t>(totalBytesWritten_));
1492         if (rendererPeriodWritten_ >= rendererPeriodSize_ && rendererPeriodSize_ > 0) {
1493             rendererPeriodWritten_ %= rendererPeriodSize_;
1494             AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRId64,
1495                 static_cast<int64_t>(rendererPeriodWritten_));
1496             SendRenderPeriodReachedEvent(rendererPeriodSize_);
1497         }
1498     }
1499 }
1500 
HandleStateChangeEvent(int64_t data)1501 void RendererInClientInner::HandleStateChangeEvent(int64_t data)
1502 {
1503     State state = INVALID;
1504     StateChangeCmdType cmdType = CMD_FROM_CLIENT;
1505     ParamsToStateCmdType(data, state, cmdType);
1506     std::unique_lock<std::mutex> lock(streamCbMutex_);
1507     std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1508     if (streamCb != nullptr) {
1509         state = state != STOPPING ? state : STOPPED; // client only need STOPPED
1510         streamCb->OnStateChange(state, cmdType);
1511     }
1512 }
1513 
HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)1514 void RendererInClientInner::HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)
1515 {
1516     AUDIO_DEBUG_LOG("Start HandleRenderMarkReachedEvent");
1517     std::unique_lock<std::mutex> lock(markReachMutex_);
1518     if (rendererPositionCallback_) {
1519         rendererPositionCallback_->OnMarkReached(rendererMarkPosition);
1520     }
1521 }
1522 
HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)1523 void RendererInClientInner::HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)
1524 {
1525     AUDIO_DEBUG_LOG("Start HandleRenderPeriodReachedEvent");
1526     std::unique_lock<std::mutex> lock(periodReachMutex_);
1527     if (rendererPeriodPositionCallback_) {
1528         rendererPeriodPositionCallback_->OnPeriodReached(rendererPeriodNumber);
1529     }
1530 }
1531 
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)1532 void RendererInClientInner::OnSpatializationStateChange(const AudioSpatializationState &spatializationState)
1533 {
1534     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
1535     CHECK_AND_RETURN_LOG(ipcStream_->UpdateSpatializationState(spatializationState.spatializationEnabled,
1536         spatializationState.headTrackingEnabled) == SUCCESS, "Update spatialization state failed");
1537 }
1538 
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)1539 void RendererInClientInner::UpdateLatencyTimestamp(std::string &timestamp, bool isRenderer)
1540 {
1541     sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
1542     if (gasp == nullptr) {
1543         AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
1544         return;
1545     }
1546     gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
1547 }
1548 
SetSourceDuration(int64_t duration)1549 int32_t RendererInClientInner::SetSourceDuration(int64_t duration)
1550 {
1551     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
1552     int32_t ret = ipcStream_->SetSourceDuration(duration);
1553     if (ret != SUCCESS) {
1554         AUDIO_ERR_LOG("Set Source Duration failed:%{public}d", ret);
1555         return ERROR;
1556     }
1557     return SUCCESS;
1558 }
1559 
GetOffloadEnable()1560 bool RendererInClientInner::GetOffloadEnable()
1561 {
1562     return offloadEnable_;
1563 }
1564 
GetSpatializationEnabled()1565 bool RendererInClientInner::GetSpatializationEnabled()
1566 {
1567     return rendererInfo_.spatializationEnabled;
1568 }
1569 
GetHighResolutionEnabled()1570 bool RendererInClientInner::GetHighResolutionEnabled()
1571 {
1572     return AudioPolicyManager::GetInstance().IsHighResolutionExist();
1573 }
1574 
SetSilentModeAndMixWithOthers(bool on)1575 void RendererInClientInner::SetSilentModeAndMixWithOthers(bool on)
1576 {
1577     AUDIO_PRERELEASE_LOGI("SetSilentModeAndMixWithOthers %{public}d", on);
1578     silentModeAndMixWithOthers_ = on;
1579     CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
1580     ipcStream_->SetSilentModeAndMixWithOthers(on);
1581     return;
1582 }
1583 
GetSilentModeAndMixWithOthers()1584 bool RendererInClientInner::GetSilentModeAndMixWithOthers()
1585 {
1586     return silentModeAndMixWithOthers_;
1587 }
1588 
RestoreAudioStream(bool needStoreState)1589 bool RendererInClientInner::RestoreAudioStream(bool needStoreState)
1590 {
1591     CHECK_AND_RETURN_RET_LOG(proxyObj_ != nullptr, false, "proxyObj_ is null");
1592     CHECK_AND_RETURN_RET_LOG(state_ != NEW && state_ != INVALID && state_ != RELEASED, true,
1593         "state_ is %{public}d, no need for restore", state_.load());
1594     bool result = true;
1595     State oldState = state_;
1596     state_ = NEW;
1597     SetStreamTrackerState(false);
1598     // If pipe type is offload, need reset to normal.
1599     // Otherwise, unable to enter offload mode.
1600     if (rendererInfo_.pipeType == PIPE_TYPE_OFFLOAD) {
1601         rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
1602     }
1603     int32_t ret = SetAudioStreamInfo(streamParams_, proxyObj_);
1604     if (ret != SUCCESS) {
1605         goto error;
1606     }
1607     if (!needStoreState) {
1608         AUDIO_INFO_LOG("telephony scene, return directly");
1609         return ret == SUCCESS;
1610     }
1611 
1612     SetDefaultOutputDevice(defaultOutputDevice_);
1613 
1614     switch (oldState) {
1615         case RUNNING:
1616             result = StartAudioStream();
1617             break;
1618         case PAUSED:
1619             result = StartAudioStream() && PauseAudioStream();
1620             break;
1621         case STOPPED:
1622         case STOPPING:
1623             result = StartAudioStream() && StopAudioStream();
1624             break;
1625         default:
1626             state_ = oldState;
1627             break;
1628     }
1629     if (!result) {
1630         goto error;
1631     }
1632     return result;
1633 
1634 error:
1635     AUDIO_ERR_LOG("RestoreAudioStream failed");
1636     state_ = oldState;
1637     return false;
1638 }
1639 
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)1640 int32_t RendererInClientInner::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
1641 {
1642     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1643     int32_t ret = ipcStream_->SetDefaultOutputDevice(defaultOutputDevice);
1644     if (ret == SUCCESS) {
1645         defaultOutputDevice_ = defaultOutputDevice;
1646     }
1647     return ret;
1648 }
1649 
GetDefaultOutputDevice()1650 DeviceType RendererInClientInner::GetDefaultOutputDevice()
1651 {
1652     return defaultOutputDevice_;
1653 }
1654 
GetAudioTimestampInfo(Timestamp & timestamp,Timestamp::Timestampbase base)1655 int32_t RendererInClientInner::GetAudioTimestampInfo(Timestamp &timestamp, Timestamp::Timestampbase base)
1656 {
1657     CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "Renderer stream state is not RUNNING");
1658     CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1659     uint64_t readIdx = 0;
1660     uint64_t timestampVal = 0;
1661     uint64_t latency = 0;
1662     int32_t ret = ipcStream_->GetAudioPosition(readIdx, timestampVal, latency);
1663     readIdx = readIdx > lastFlushReadIndex_ ? readIdx - lastFlushReadIndex_ : 0;
1664     uint64_t framePosition = lastFramePosition_;
1665     if (readIdx >= latency + lastReadIdx_) { // happen when last speed latency consumed
1666         framePosition += lastLatencyPosition_ + (readIdx - lastReadIdx_ - latency) * speed_;
1667         lastLatency_ = latency;
1668         lastLatencyPosition_ = latency * speed_;
1669         lastReadIdx_ = readIdx;
1670     } else { // happen when last speed latency not consumed
1671         if (lastLatency_ + readIdx > latency + lastReadIdx_) {
1672             framePosition += lastLatencyPosition_ * (lastLatency_ + readIdx - latency - lastReadIdx_) / lastLatency_;
1673             lastLatencyPosition_ = lastLatencyPosition_ * (latency + lastReadIdx_ - readIdx) / lastLatency_;
1674             lastLatency_ = latency + lastReadIdx_ - readIdx;
1675         }
1676     }
1677     // add MCR latency
1678     uint32_t mcrLatency = 0;
1679     if (converter_ != nullptr) {
1680         mcrLatency = converter_->GetLatency() * curStreamParams_.samplingRate / AUDIO_MS_PER_S;
1681         framePosition = framePosition > mcrLatency ? framePosition - mcrLatency : 0;
1682     }
1683 
1684     if (lastFramePosition_ < framePosition) {
1685         lastFramePosition_ = framePosition;
1686         lastFrameTimestamp_ = timestampVal;
1687     } else {
1688         AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
1689         framePosition = lastFramePosition_;
1690         timestampVal = lastFrameTimestamp_;
1691     }
1692     AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
1693         ", timestamp %{public}" PRIu64 ", lastLatencyPosition_ %{public}" PRIu64 ", totlatency %{public}" PRIu64,
1694         framePosition, lastFlushReadIndex_, timestampVal, lastLatencyPosition_, latency + mcrLatency);
1695 
1696     timestamp.framePosition = framePosition;
1697     timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
1698     timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
1699     return ret;
1700 }
1701 
SetSwitchingStatus(bool isSwitching)1702 void RendererInClientInner::SetSwitchingStatus(bool isSwitching)
1703 {
1704     std::lock_guard lock(switchingMutex_);
1705     if (isSwitching) {
1706         switchingInfo_ = {true, state_};
1707     } else {
1708         switchingInfo_ = {false, INVALID};
1709     }
1710 }
1711 
GetRestoreInfo(RestoreInfo & restoreInfo)1712 void RendererInClientInner::GetRestoreInfo(RestoreInfo &restoreInfo)
1713 {
1714     CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1715     clientBuffer_->GetRestoreInfo(restoreInfo);
1716     return;
1717 }
1718 
SetRestoreInfo(RestoreInfo & restoreInfo)1719 void RendererInClientInner::SetRestoreInfo(RestoreInfo &restoreInfo)
1720 {
1721     if (restoreInfo.restoreReason == SERVER_DIED) {
1722         cbThreadReleased_ = true;
1723     }
1724     CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1725     clientBuffer_->SetRestoreInfo(restoreInfo);
1726     return;
1727 }
1728 
CheckRestoreStatus()1729 RestoreStatus RendererInClientInner::CheckRestoreStatus()
1730 {
1731     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1732     return clientBuffer_->CheckRestoreStatus();
1733 }
1734 
SetRestoreStatus(RestoreStatus restoreStatus)1735 RestoreStatus RendererInClientInner::SetRestoreStatus(RestoreStatus restoreStatus)
1736 {
1737     CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1738     return clientBuffer_->SetRestoreStatus(restoreStatus);
1739 }
1740 
FetchDeviceForSplitStream()1741 void RendererInClientInner::FetchDeviceForSplitStream()
1742 {
1743     AUDIO_INFO_LOG("Fetch output device for split stream %{public}u", sessionId_);
1744     if (audioStreamTracker_ && audioStreamTracker_.get()) {
1745         audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_,
1746             state_, clientPid_, rendererInfo_, AudioStreamDeviceChangeReasonExt::ExtEnum::UNKNOWN);
1747     } else {
1748         AUDIO_WARNING_LOG("Tracker is nullptr, fail to split stream %{public}u", sessionId_);
1749     }
1750     SetRestoreStatus(NO_NEED_FOR_RESTORE);
1751 }
1752 } // namespace AudioStandard
1753 } // namespace OHOS