1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "FastAudioRendererSinkInner"
17 #endif
18 
19 #include "fast_audio_renderer_sink.h"
20 
21 #include <cinttypes>
22 #include <climits>
23 #include <cstdio>
24 #include <cstring>
25 #include <dlfcn.h>
26 #include <list>
27 #include <mutex>
28 #include <string>
29 #include <unistd.h>
30 
31 #include <sys/mman.h>
32 #ifdef FEATURE_POWER_MANAGER
33 #include "power_mgr_client.h"
34 #include "running_lock.h"
35 #include "audio_running_lock_manager.h"
36 #endif
37 #include "securec.h"
38 #include "v4_0/iaudio_manager.h"
39 
40 #include "audio_errors.h"
41 #include "audio_hdi_log.h"
42 #include "audio_utils.h"
43 
44 using namespace std;
45 
46 namespace OHOS {
47 namespace AudioStandard {
48 namespace {
49 const int32_t HALF_FACTOR = 2;
50 const uint32_t MAX_AUDIO_ADAPTER_NUM = 5;
51 const float DEFAULT_VOLUME_LEVEL = 1.0f;
52 const uint32_t AUDIO_CHANNELCOUNT = 2;
53 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 3840;
54 const uint32_t INT_32_MAX = 0x7fffffff;
55 const uint32_t PCM_8_BIT = 8;
56 const uint32_t PCM_16_BIT = 16;
57 const uint32_t PCM_24_BIT = 24;
58 const uint32_t PCM_32_BIT = 32;
59 const int64_t SECOND_TO_NANOSECOND = 1000000000;
60 const int INVALID_FD = -1;
61 const unsigned int XCOLLIE_TIME_OUT_SECONDS = 10;
62 }
63 
64 class FastAudioRendererSinkInner : public FastAudioRendererSink {
65 public:
66     int32_t Init(const IAudioSinkAttr &attr) override;
67     bool IsInited(void) override;
68     void DeInit(void) override;
69 
70     int32_t Start(void) override;
71     int32_t Stop(void) override;
72     int32_t Flush(void) override;
73     int32_t Reset(void) override;
74     int32_t Pause(void) override;
75     int32_t Resume(void) override;
76 
77     int32_t SuspendRenderSink(void) override;
78     int32_t RestoreRenderSink(void) override;
79 
80     int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override;
81     int32_t SetVolume(float left, float right) override;
82     int32_t GetVolume(float &left, float &right) override;
83     int32_t SetVoiceVolume(float volume) override;
84     int32_t GetLatency(uint32_t *latency) override;
85     int32_t GetTransactionId(uint64_t *transactionId) override;
86     int32_t SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices) override;
87     int32_t SetOutputRoutes(std::vector<DeviceType> &outputDevices) override;
88     void ResetOutputRouteForDisconnect(DeviceType device) override;
89 
90     void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override;
91     std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override;
92     void RegisterParameterCallback(IAudioSinkCallback* callback) override;
93 
94     void SetAudioMonoState(bool audioMono) override;
95     void SetAudioBalanceValue(float audioBalance) override;
96 
97     int32_t GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) override;
98 
99     int32_t GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
100         uint32_t &byteSizePerFrame) override;
101     int32_t GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) override;
102     float GetMaxAmplitude() override;
103     int32_t SetPaPower(int32_t flag) override;
104     int32_t SetPriPaPower() override;
105 
106     int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final;
107     int32_t UpdateAppsUid(const std::vector<int32_t> &appsUid) final;
108 
109     FastAudioRendererSinkInner();
110     ~FastAudioRendererSinkInner();
111 
112 private:
113 #ifdef FEATURE_POWER_MANAGER
114     void KeepRunningLock();
115     void KeepRunningUnlock();
116 #endif
117     int32_t PrepareMmapBuffer();
118     void ReleaseMmapBuffer();
119 
120     int32_t CheckPositionTime();
121     void PreparePosition();
122 
123     void InitAttrs(struct AudioSampleAttributes &attrs);
124     AudioFormat ConvertToHdiFormat(HdiAdapterFormat format);
125     int32_t CreateRender(const struct AudioPort &renderPort);
126     int32_t InitAudioManager();
127 
128 private:
129     IAudioSinkAttr attr_ = {};
130     bool rendererInited_ = false;
131     bool started_ = false;
132     bool paused_ = false;
133     float leftVolume_ = 0.0f;
134     float rightVolume_ = 0.0f;
135     int32_t routeHandle_ = -1;
136     std::string adapterNameCase_ = "";
137     struct IAudioManager *audioManager_ = nullptr;
138     struct IAudioAdapter *audioAdapter_ = nullptr;
139     struct IAudioRender *audioRender_ = nullptr;
140     struct AudioAdapterDescriptor adapterDesc_ = {};
141     struct AudioPort audioPort_ = {};
142     uint32_t renderId_ = 0;
143 
144     size_t bufferSize_ = 0;
145     uint32_t bufferTotalFrameSize_ = 0;
146 
147     int bufferFd_ = INVALID_FD;
148     uint32_t frameSizeInByte_ = 1;
149     uint32_t eachReadFrameSize_ = 0;
150     std::mutex mutex_;
151 #ifdef FEATURE_POWER_MANAGER
152     std::shared_ptr<AudioRunningLockManager<PowerMgr::RunningLock>> runningLockManager_;
153 #endif
154 
155 #ifdef DEBUG_DIRECT_USE_HDI
156     char *bufferAddresss_ = nullptr;
157     bool isFirstWrite_ = true;
158     uint64_t alreadyReadFrames_ = 0;
159     uint32_t curReadPos_ = 0;
160     uint32_t curWritePos_ = 0;
161     uint32_t writeAheadPeriod_ = 1;
162 
163     int privFd_ = INVALID_FD; // invalid fd
164 #endif
165 };  // FastAudioRendererSinkInner
166 
FastAudioRendererSinkInner()167 FastAudioRendererSinkInner::FastAudioRendererSinkInner()
168     : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
169       rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr),
170       audioRender_(nullptr)
171 {
172     attr_ = {};
173 }
174 
~FastAudioRendererSinkInner()175 FastAudioRendererSinkInner::~FastAudioRendererSinkInner()
176 {
177     FastAudioRendererSinkInner::DeInit();
178 }
179 
GetInstance()180 IMmapAudioRendererSink *FastAudioRendererSink::GetInstance()
181 {
182     static FastAudioRendererSinkInner audioRenderer;
183 
184     return &audioRenderer;
185 }
186 
GetVoipInstance()187 IMmapAudioRendererSink *FastAudioRendererSink::GetVoipInstance()
188 {
189     static FastAudioRendererSinkInner audioVoipRenderer;
190 
191     return &audioVoipRenderer;
192 }
193 
CreateFastRendererSink()194 std::shared_ptr<IMmapAudioRendererSink> FastAudioRendererSink::CreateFastRendererSink()
195 {
196     std::shared_ptr<IMmapAudioRendererSink> audioRenderer = std::make_shared<FastAudioRendererSinkInner>();
197 
198     return audioRenderer;
199 }
200 
IsInited()201 bool FastAudioRendererSinkInner::IsInited()
202 {
203     return rendererInited_;
204 }
205 
DeInit()206 void FastAudioRendererSinkInner::DeInit()
207 {
208 #ifdef FEATURE_POWER_MANAGER
209     KeepRunningUnlock();
210 
211 #endif
212 
213     started_ = false;
214     rendererInited_ = false;
215     if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
216         audioAdapter_->DestroyRender(audioAdapter_, renderId_);
217     }
218     audioRender_ = nullptr;
219 
220     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
221         if (routeHandle_ != -1) {
222             audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
223         }
224         audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
225     }
226     audioAdapter_ = nullptr;
227     audioManager_ = nullptr;
228 
229     ReleaseMmapBuffer();
230 }
231 
InitAttrs(struct AudioSampleAttributes & attrs)232 void FastAudioRendererSinkInner::InitAttrs(struct AudioSampleAttributes &attrs)
233 {
234     /* Initialization of audio parameters for playback */
235     attrs.channelCount = AUDIO_CHANNELCOUNT;
236     attrs.interleaved = true;
237     attrs.streamId = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ?
238         static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP_FAST)) :
239         static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_FAST));
240     attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
241     attrs.isBigEndian = false;
242     attrs.isSignedData = true;
243     attrs.stopThreshold = INT_32_MAX;
244     attrs.silenceThreshold = 0;
245 }
246 
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)247 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
248     enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
249 {
250     if (descs == nullptr) {
251         return ERROR;
252     }
253     for (int32_t index = 0; index < size; index++) {
254         struct AudioAdapterDescriptor *desc = &descs[index];
255         if (desc == nullptr || desc->adapterName == nullptr) {
256             continue;
257         }
258         if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
259             continue;
260         }
261         for (uint32_t port = 0; port < desc->portsLen; port++) {
262             // Only find out the port of out in the sound card
263             if (desc->ports[port].dir == portFlag) {
264                 renderPort = desc->ports[port];
265                 return index;
266             }
267         }
268     }
269     AUDIO_ERR_LOG("SwitchAdapterRender Fail");
270 
271     return ERR_INVALID_INDEX;
272 }
273 
InitAudioManager()274 int32_t FastAudioRendererSinkInner::InitAudioManager()
275 {
276     AUDIO_INFO_LOG("Initialize audio proxy manager");
277 
278     audioManager_ = IAudioManagerGet(false);
279     if (audioManager_ == nullptr) {
280         return ERR_INVALID_HANDLE;
281     }
282 
283     return 0;
284 }
285 
PcmFormatToBits(HdiAdapterFormat format)286 uint32_t PcmFormatToBits(HdiAdapterFormat format)
287 {
288     switch (format) {
289         case SAMPLE_U8:
290             return PCM_8_BIT;
291         case SAMPLE_S16LE:
292             return PCM_16_BIT;
293         case SAMPLE_S24LE:
294             return PCM_24_BIT;
295         case SAMPLE_S32LE:
296             return PCM_32_BIT;
297         case SAMPLE_F32LE:
298             return PCM_32_BIT;
299         default:
300             return PCM_24_BIT;
301     }
302 }
303 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame)304 int32_t FastAudioRendererSinkInner::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
305     uint32_t &byteSizePerFrame)
306 {
307     CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released!");
308     fd = bufferFd_;
309     totalSizeInframe = bufferTotalFrameSize_;
310     spanSizeInframe = eachReadFrameSize_;
311     byteSizePerFrame = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
312     return SUCCESS;
313 }
314 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)315 int32_t FastAudioRendererSinkInner::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
316 {
317     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio render is null!");
318 
319     struct AudioTimeStamp timestamp = {};
320     int32_t ret = audioRender_->GetMmapPosition(audioRender_, &frames, &timestamp);
321     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "Hdi GetMmapPosition filed, ret:%{public}d!", ret);
322 #ifdef DEBUG_DIRECT_USE_HDI
323     alreadyReadFrames_ = frames; // frames already read.
324     curReadPos_ = frameSizeInByte_ * (frames - bufferTotalFrameSize_ * (frames / bufferTotalFrameSize_));
325     CHECK_AND_RETURN_RET_LOG((curReadPos_ >= 0 && curReadPos_ < bufferSize_), ERR_INVALID_PARAM, "curReadPos invalid");
326     AUDIO_DEBUG_LOG("GetMmapHandlePosition frames[:%{public}" PRIu64 "] tvsec:%{public}" PRId64 " tvNSec:"
327         "%{public}" PRId64 " alreadyReadFrames:%{public}" PRId64 " curReadPos[%{public}d]",
328         frames, timestamp.tvSec, timestamp.tvNSec, alreadyReadFrames_, curReadPos_);
329 #endif
330 
331     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it.
332     CHECK_AND_RETURN_RET_LOG(timestamp.tvSec >= 0 && timestamp.tvSec <= maxSec && timestamp.tvNSec >= 0 &&
333         timestamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
334         "Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !",
335         timestamp.tvSec, timestamp.tvNSec);
336     timeSec = timestamp.tvSec;
337     timeNanoSec = timestamp.tvNSec;
338 
339     return SUCCESS;
340 }
341 
ReleaseMmapBuffer()342 void FastAudioRendererSinkInner::ReleaseMmapBuffer()
343 {
344 #ifdef DEBUG_DIRECT_USE_HDI
345     if (bufferAddresss_ != nullptr) {
346         munmap(bufferAddresss_, bufferSize_);
347         bufferAddresss_ = nullptr;
348         bufferSize_ = 0;
349         AUDIO_INFO_LOG("ReleaseMmapBuffer end.");
350     } else {
351         AUDIO_WARNING_LOG("ReleaseMmapBuffer buffer already null.");
352     }
353     if (privFd_ != INVALID_FD) {
354         CloseFd(privFd_);
355         privFd_ = INVALID_FD;
356     }
357 #endif
358     if (bufferFd_ != INVALID_FD) {
359         CloseFd(bufferFd_);
360         bufferFd_ = INVALID_FD;
361     }
362 }
363 
PrepareMmapBuffer()364 int32_t FastAudioRendererSinkInner::PrepareMmapBuffer()
365 {
366     uint32_t totalBufferInMs = 40; // 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency.
367     frameSizeInByte_ = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
368     uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / 1000);
369 
370     struct AudioMmapBufferDescriptor desc = {0};
371     int32_t ret = audioRender_->ReqMmapBuffer(audioRender_, reqBufferFrameSize, &desc);
372     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "ReqMmapBuffer failed, ret:%{public}d", ret);
373     AUDIO_INFO_LOG("AudioMmapBufferDescriptor memoryAddress[%{private}p] memoryFd[%{public}d] totalBufferFrames"
374         "[%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]", desc.memoryAddress,
375         desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable, desc.offset);
376 
377     bufferFd_ = desc.memoryFd; // fcntl(fd, 1030,3) after dup?
378     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
379     CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
380         desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
381         "ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]",
382         desc.totalBufferFrames, desc.transferFrameSize);
383     bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
384     eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
385 
386     CHECK_AND_RETURN_RET_LOG(frameSizeInByte_ <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
387         "BufferSize will overflow!");
388     bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte_;
389 #ifdef DEBUG_DIRECT_USE_HDI
390     privFd_ = dup(bufferFd_);
391     bufferAddresss_ = (char *)mmap(nullptr, bufferSize_, PROT_READ | PROT_WRITE, MAP_SHARED, privFd_, 0);
392     CHECK_AND_RETURN_RET_LOG(bufferAddresss_ != nullptr && bufferAddresss_ != MAP_FAILED, ERR_OPERATION_FAILED,
393         "mmap buffer failed!");
394 #endif
395     return SUCCESS;
396 }
397 
ConvertToHdiFormat(HdiAdapterFormat format)398 AudioFormat FastAudioRendererSinkInner::ConvertToHdiFormat(HdiAdapterFormat format)
399 {
400     AudioFormat hdiFormat;
401     switch (format) {
402         case SAMPLE_U8:
403             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
404             break;
405         case SAMPLE_S16:
406             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
407             break;
408         case SAMPLE_S24:
409             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
410             break;
411         case SAMPLE_S32:
412             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
413             break;
414         default:
415             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
416             break;
417     }
418 
419     return hdiFormat;
420 }
421 
CreateRender(const struct AudioPort & renderPort)422 int32_t FastAudioRendererSinkInner::CreateRender(const struct AudioPort &renderPort)
423 {
424     int32_t ret;
425     struct AudioSampleAttributes param;
426     InitAttrs(param);
427     param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ;
428     param.sampleRate = attr_.sampleRate;
429     param.channelCount = attr_.channel;
430     if (param.channelCount == MONO) {
431         param.channelLayout = CH_LAYOUT_MONO;
432     } else if (param.channelCount == STEREO) {
433         param.channelLayout = CH_LAYOUT_STEREO;
434     }
435     param.format = ConvertToHdiFormat(attr_.format);
436     param.frameSize = PcmFormatToBits(attr_.format) * param.channelCount / PCM_8_BIT;
437     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); // not passed in hdi
438     AUDIO_INFO_LOG("Type: %{public}d, sampleRate: %{public}u, channel: %{public}d, format: %{public}d, "
439         "device:%{public}d", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType);
440     struct AudioDeviceDescriptor deviceDesc;
441     deviceDesc.portId = renderPort.portId;
442     switch (static_cast<DeviceType>(attr_.deviceType)) {
443         case DEVICE_TYPE_EARPIECE:
444             deviceDesc.pins = PIN_OUT_EARPIECE;
445             break;
446         case DEVICE_TYPE_SPEAKER:
447             deviceDesc.pins = PIN_OUT_SPEAKER;
448             break;
449         case DEVICE_TYPE_WIRED_HEADSET:
450             deviceDesc.pins = PIN_OUT_HEADSET;
451             break;
452         case DEVICE_TYPE_USB_HEADSET:
453             deviceDesc.pins = PIN_OUT_USB_EXT;
454             break;
455         case DEVICE_TYPE_BLUETOOTH_SCO:
456             deviceDesc.pins = PIN_OUT_BLUETOOTH_SCO;
457             break;
458         default:
459             deviceDesc.pins = PIN_OUT_SPEAKER;
460             break;
461     }
462     char desc[] = "";
463     deviceDesc.desc = desc;
464     ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, &param, &audioRender_, &renderId_);
465     if (ret != 0 || audioRender_ == nullptr) {
466         AUDIO_ERR_LOG("AudioDeviceCreateRender failed, ret is :%{public}d", ret);
467         audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
468         return ERR_NOT_STARTED;
469     }
470 
471     return SUCCESS;
472 }
473 
Init(const IAudioSinkAttr & attr)474 int32_t FastAudioRendererSinkInner::Init(const IAudioSinkAttr &attr)
475 {
476     AUDIO_INFO_LOG("FastAudioRendererSinkInner::Init");
477     attr_ = attr;
478     adapterNameCase_ = attr_.adapterName;  // Set sound card information
479     enum AudioPortDirection port = PORT_OUT; // Set port information
480 
481     CHECK_AND_RETURN_RET_LOG(InitAudioManager() == 0, ERR_NOT_STARTED, "Init audio manager Fail");
482 
483     uint32_t size = MAX_AUDIO_ADAPTER_NUM;
484     AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM];
485     if (audioManager_ == nullptr) {
486         AUDIO_ERR_LOG("The audioManager is nullptr!");
487         return ERROR;
488     }
489     int32_t ret = audioManager_->GetAllAdapters(audioManager_,
490         (struct AudioAdapterDescriptor *)&descs, &size);
491     CHECK_AND_RETURN_RET_LOG(size <= MAX_AUDIO_ADAPTER_NUM && size != 0 && ret == 0, ERR_NOT_STARTED,
492         "Get adapters Fail");
493 
494     int32_t index = SwitchAdapterRender((struct AudioAdapterDescriptor *)&descs, adapterNameCase_, port, audioPort_,
495         size);
496     CHECK_AND_RETURN_RET_LOG(index >= 0, ERR_NOT_STARTED, "Switch Adapter Fail");
497 
498     adapterDesc_ = descs[index];
499     int32_t result = audioManager_->LoadAdapter(audioManager_, &adapterDesc_, &audioAdapter_);
500     CHECK_AND_RETURN_RET_LOG(result == 0, ERR_NOT_STARTED, "Load Adapter Fail");
501     CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, ERR_NOT_STARTED, "Load audio device failed");
502 
503     // Initialization port information, can fill through mode and other parameters
504     ret = audioAdapter_->InitAllPorts(audioAdapter_);
505     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED, "InitAllPorts failed");
506 
507     CHECK_AND_RETURN_RET_LOG(CreateRender(audioPort_) == SUCCESS && PrepareMmapBuffer() == SUCCESS,
508         ERR_NOT_STARTED, "Create render failed, Audio Port: %{public}d", audioPort_.portId);
509 
510     rendererInited_ = true;
511 
512     return SUCCESS;
513 }
514 
PreparePosition()515 void FastAudioRendererSinkInner::PreparePosition()
516 {
517 #ifdef DEBUG_DIRECT_USE_HDI
518     isFirstWrite_ = false;
519     uint64_t frames = 0;
520     int64_t timeSec = 0;
521     int64_t timeNanoSec = 0;
522     GetMmapHandlePosition(frames, timeSec, timeNanoSec); // get first start position
523     int32_t periodByteSize = eachReadFrameSize_ * frameSizeInByte_;
524     CHECK_AND_RETURN_LOG(periodByteSize * writeAheadPeriod_ <= ULLONG_MAX - curReadPos_, "TempPos will overflow!");
525     size_t tempPos = curReadPos_ + periodByteSize * writeAheadPeriod_; // 1 period ahead
526     curWritePos_ = (tempPos < bufferSize_ ? tempPos : tempPos - bufferSize_);
527     AUDIO_INFO_LOG("First render frame start with curReadPos_[%{public}d] curWritePos_[%{public}d]", curReadPos_,
528         curWritePos_);
529 #endif
530 }
531 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)532 int32_t FastAudioRendererSinkInner::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
533 {
534 #ifdef DEBUG_DIRECT_USE_HDI
535     int64_t stamp = ClockTime::GetCurNano();
536     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio Render Handle is nullptr!");
537 
538     if (len > (bufferSize_ - eachReadFrameSize_ * frameSizeInByte_ * writeAheadPeriod_)) {
539         writeLen = 0;
540         AUDIO_ERR_LOG("RenderFrame failed,too large len[%{public}" PRIu64 "]!", len);
541         return ERR_WRITE_FAILED;
542     }
543 
544     if (isFirstWrite_) {
545         PreparePosition();
546     }
547 
548     CHECK_AND_RETURN_RET_LOG((curWritePos_ >= 0 && curWritePos_ < bufferSize_), ERR_INVALID_PARAM,
549         "curWritePos_ invalid");
550     char *writePtr = bufferAddresss_ + curWritePos_;
551     uint64_t dataBefore = *(uint64_t *)writePtr;
552     uint64_t dataAfter = 0;
553     uint64_t tempPos = curWritePos_ + len;
554     if (tempPos <= bufferSize_) {
555         if (memcpy_s(writePtr, (bufferSize_ - curWritePos_), static_cast<void *>(&data), len)) {
556             AUDIO_ERR_LOG("copy failed");
557             return ERR_WRITE_FAILED;
558         }
559         dataAfter = *(uint64_t *)writePtr;
560         curWritePos_ = (tempPos == bufferSize_ ? 0 : tempPos);
561     } else {
562         AUDIO_DEBUG_LOG("(tempPos%{public}" PRIu64 ")curWritePos_ + len > bufferSize_", tempPos);
563         size_t writeableSize = bufferSize_ - curWritePos_;
564         if (memcpy_s(writePtr, writeableSize, static_cast<void *>(&data), writeableSize) ||
565             memcpy_s(bufferAddresss_, bufferSize_, static_cast<void *>((char *)&data + writeableSize),
566             (len - writeableSize))) {
567             AUDIO_ERR_LOG("copy failed");
568             return ERR_WRITE_FAILED;
569         }
570         curWritePos_ = len - writeableSize;
571     }
572     writeLen = len;
573 
574     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
575     AUDIO_DEBUG_LOG("Render len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms curWritePos[%{public}d] dataBefore"
576         "<%{public}" PRIu64 "> dataAfter<%{public}" PRIu64 ">", len, stamp, curWritePos_, dataBefore, dataAfter);
577     return SUCCESS;
578 #else
579     AUDIO_WARNING_LOG("RenderFrame is not supported.");
580     return ERR_NOT_SUPPORTED;
581 #endif
582 }
583 
GetMaxAmplitude()584 float FastAudioRendererSinkInner::GetMaxAmplitude()
585 {
586     AUDIO_WARNING_LOG("getMaxAmplitude in fast_audio_renderder_sink not support");
587     return 0;
588 }
589 
SetPaPower(int32_t flag)590 int32_t FastAudioRendererSinkInner::SetPaPower(int32_t flag)
591 {
592     (void)flag;
593     return ERR_NOT_SUPPORTED;
594 }
595 
SetPriPaPower()596 int32_t FastAudioRendererSinkInner::SetPriPaPower()
597 {
598     return ERR_NOT_SUPPORTED;
599 }
600 
CheckPositionTime()601 int32_t FastAudioRendererSinkInner::CheckPositionTime()
602 {
603     int32_t tryCount = 50;
604     uint64_t frames = 0;
605     int64_t timeSec = 0;
606     int64_t timeNanoSec = 0;
607     int64_t maxHandleCost = 10000000; // ns
608     int64_t waitTime = 2000000; // 2ms
609     while (tryCount-- > 0) {
610         ClockTime::RelativeSleep(waitTime); // us
611         int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
612         int64_t curTime = ClockTime::GetCurNano();
613         int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
614         int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
615         if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > maxHandleCost) {
616             AUDIO_WARNING_LOG("CheckPositionTime[%{public}d]:ret %{public}d", tryCount, ret);
617             continue;
618         } else {
619             AUDIO_INFO_LOG("CheckPositionTime end, position and time is ok.");
620             return SUCCESS;
621         }
622     }
623     return ERROR;
624 }
625 
Start(void)626 int32_t FastAudioRendererSinkInner::Start(void)
627 {
628     std::lock_guard<std::mutex> lock(mutex_);
629     Trace trace("FastAudioRendererSinkInner::Start");
630     AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Start", XCOLLIE_TIME_OUT_SECONDS);
631     AUDIO_INFO_LOG("FastAudioRendererSinkInner::Start");
632     int64_t stamp = ClockTime::GetCurNano();
633     int32_t ret;
634 
635     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
636         "FastAudioRendererSink::Start audioRender_ null!");
637 
638     if (!started_) {
639         ret = audioRender_->Start(audioRender_);
640         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED,
641             "FastAudioRendererSink::Start failed!");
642         int32_t err = CheckPositionTime();
643         CHECK_AND_RETURN_RET_LOG(err == SUCCESS, ERR_NOT_STARTED,
644             "FastAudioRendererSink::CheckPositionTime failed!");
645     }
646 #ifdef FEATURE_POWER_MANAGER
647     KeepRunningLock();
648 #endif
649     started_ = true;
650     AUDIO_DEBUG_LOG("Start cost[%{public}" PRId64 "]ms", (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND);
651     return SUCCESS;
652 }
653 #ifdef FEATURE_POWER_MANAGER
KeepRunningLock()654 void FastAudioRendererSinkInner::KeepRunningLock()
655 {
656     std::shared_ptr<PowerMgr::RunningLock> keepRunningLock;
657     if (runningLockManager_ == nullptr) {
658         WatchTimeout guard("PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock:KeepRunningLock");
659         keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioFastBackgroundPlay",
660             PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO);
661         guard.CheckCurrTimeout();
662         if (keepRunningLock) {
663             runningLockManager_ = std::make_shared<AudioRunningLockManager<PowerMgr::RunningLock>> (keepRunningLock);
664         }
665     }
666 
667     if (runningLockManager_ != nullptr) {
668         int32_t timeOut = -1; // -1 for lasting.
669         AUDIO_INFO_LOG("keepRunningLock lock result: %{public}d",
670             runningLockManager_->Lock(timeOut)); // -1 for lasting.
671     } else {
672         AUDIO_ERR_LOG("keepRunningLock is null, playback can not work well!");
673     }
674 }
675 #endif
676 
677 #ifdef FEATURE_POWER_MANAGER
KeepRunningUnlock()678 void FastAudioRendererSinkInner::KeepRunningUnlock()
679 {
680     if (runningLockManager_ != nullptr) {
681         AUDIO_INFO_LOG("keepRunningLock unLock");
682         runningLockManager_->UnLock();
683     } else {
684         AUDIO_WARNING_LOG("keepRunningLock is null, playback can not work well!");
685     }
686 }
687 #endif
688 
689 
SetVolume(float left,float right)690 int32_t FastAudioRendererSinkInner::SetVolume(float left, float right)
691 {
692     int32_t ret;
693     float volume;
694 
695     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
696         "FastAudioRendererSink::SetVolume failed audioRender_ null");
697 
698     leftVolume_ = left;
699     rightVolume_ = right;
700     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
701         volume = rightVolume_;
702     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
703         volume = leftVolume_;
704     } else {
705         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
706     }
707 
708     AUDIO_INFO_LOG("Set hdi volume to %{public}f", volume);
709     ret = audioRender_->SetVolume(audioRender_, volume);
710     if (ret) {
711         AUDIO_ERR_LOG("FastAudioRendererSink::Set volume failed!");
712     }
713 
714     return ret;
715 }
716 
GetVolume(float & left,float & right)717 int32_t FastAudioRendererSinkInner::GetVolume(float &left, float &right)
718 {
719     left = leftVolume_;
720     right = rightVolume_;
721     return SUCCESS;
722 }
723 
SetVoiceVolume(float volume)724 int32_t FastAudioRendererSinkInner::SetVoiceVolume(float volume)
725 {
726     AUDIO_ERR_LOG("FastAudioRendererSink SetVoiceVolume not supported.");
727     return ERR_NOT_SUPPORTED;
728 }
729 
SetAudioScene(AudioScene audioScene,std::vector<DeviceType> & activeDevices)730 int32_t FastAudioRendererSinkInner::SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices)
731 {
732     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioScene not supported.");
733     return ERR_NOT_SUPPORTED;
734 }
735 
SetOutputRoutes(std::vector<DeviceType> & outputDevices)736 int32_t FastAudioRendererSinkInner::SetOutputRoutes(std::vector<DeviceType> &outputDevices)
737 {
738     AUDIO_ERR_LOG("SetOutputRoutes not supported.");
739     return ERR_NOT_SUPPORTED;
740 }
741 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)742 void FastAudioRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string &condition,
743     const std::string &value)
744 {
745     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioParameter not supported.");
746     return;
747 }
748 
GetAudioParameter(const AudioParamKey key,const std::string & condition)749 std::string FastAudioRendererSinkInner::GetAudioParameter(const AudioParamKey key, const std::string &condition)
750 {
751     AUDIO_INFO_LOG("GetAudioParameter, key: %{public}d, condition: %{public}s",
752         key, condition.c_str());
753     AudioExtParamKey hdiKey = AudioExtParamKey(key);
754     char value[PARAM_VALUE_LENTH];
755     CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, "",
756         "GetAudioParameter failed, audioAdapter_ is null");
757     int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(),
758         value, PARAM_VALUE_LENTH);
759     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "",
760         "FRSink GetAudioParameter failed, error code:%{public}d", ret);
761     return value;
762 }
763 
RegisterParameterCallback(IAudioSinkCallback * callback)764 void FastAudioRendererSinkInner::RegisterParameterCallback(IAudioSinkCallback* callback)
765 {
766     AUDIO_ERR_LOG("FastAudioRendererSink RegisterParameterCallback not supported.");
767 }
768 
SetAudioMonoState(bool audioMono)769 void FastAudioRendererSinkInner::SetAudioMonoState(bool audioMono)
770 {
771     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioMonoState not supported.");
772     return;
773 }
774 
SetAudioBalanceValue(float audioBalance)775 void FastAudioRendererSinkInner::SetAudioBalanceValue(float audioBalance)
776 {
777     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioBalanceValue not supported.");
778     return;
779 }
780 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)781 int32_t FastAudioRendererSinkInner::GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec)
782 {
783     AUDIO_ERR_LOG("FastAudioRendererSink GetPresentationPosition not supported.");
784     return ERR_NOT_SUPPORTED;
785 }
786 
GetTransactionId(uint64_t * transactionId)787 int32_t FastAudioRendererSinkInner::GetTransactionId(uint64_t *transactionId)
788 {
789     AUDIO_ERR_LOG("FastAudioRendererSink %{public}s", __func__);
790     *transactionId = 6; // 6 is the mmap device.
791     return ERR_NOT_SUPPORTED;
792 }
793 
GetLatency(uint32_t * latency)794 int32_t FastAudioRendererSinkInner::GetLatency(uint32_t *latency)
795 {
796     Trace trace("FastAudioRendererSinkInner::GetLatency");
797     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
798         "GetLatency failed audio render null");
799 
800     CHECK_AND_RETURN_RET_LOG(latency, ERR_INVALID_PARAM,
801         "GetLatency failed latency null");
802 
803     uint32_t hdiLatency;
804     if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
805         *latency = hdiLatency;
806         return SUCCESS;
807     } else {
808         return ERR_OPERATION_FAILED;
809     }
810 }
811 
Stop(void)812 int32_t FastAudioRendererSinkInner::Stop(void)
813 {
814     std::lock_guard<std::mutex> lock(mutex_);
815     Trace trace("FastAudioRendererSinkInner::Stop");
816     AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Stop", XCOLLIE_TIME_OUT_SECONDS);
817     AUDIO_INFO_LOG("Stop.");
818 
819     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
820         "Stop failed audioRender_ null");
821 #ifdef FEATURE_POWER_MANAGER
822     KeepRunningUnlock();
823 #endif
824 
825     if (started_) {
826         int32_t ret = audioRender_->Stop(audioRender_);
827         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
828             "Stop failed! ret: %{public}d.", ret);
829     }
830     started_ = false;
831 
832     return SUCCESS;
833 }
834 
Pause(void)835 int32_t FastAudioRendererSinkInner::Pause(void)
836 {
837     int32_t ret;
838 
839     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
840         "Pause failed audioRender_ null");
841 
842     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
843         "Pause invalid state!");
844 
845     if (!paused_) {
846         ret = audioRender_->Pause(audioRender_);
847         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
848             "Pause failed!");
849     }
850     paused_ = true;
851 
852     return SUCCESS;
853 }
854 
Resume(void)855 int32_t FastAudioRendererSinkInner::Resume(void)
856 {
857     Trace trace("FastAudioRendererSinkInner::Resume");
858     int32_t ret;
859 
860     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
861         "Resume failed audioRender_ null");
862 
863     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
864         "Resume invalid state!");
865 
866     if (paused_) {
867         ret = audioRender_->Resume(audioRender_);
868         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
869             "Resume failed!");
870     }
871     paused_ = false;
872 
873     return SUCCESS;
874 }
875 
SuspendRenderSink(void)876 int32_t FastAudioRendererSinkInner::SuspendRenderSink(void)
877 {
878     return SUCCESS;
879 }
880 
RestoreRenderSink(void)881 int32_t FastAudioRendererSinkInner::RestoreRenderSink(void)
882 {
883     return SUCCESS;
884 }
885 
Reset(void)886 int32_t FastAudioRendererSinkInner::Reset(void)
887 {
888     Trace trace("FastAudioRendererSinkInner::Reset");
889     int32_t ret;
890 
891     if (started_ && audioRender_ != nullptr) {
892         ret = audioRender_->Flush(audioRender_);
893 
894         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
895             "Reset failed!");
896     }
897 
898     return SUCCESS;
899 }
900 
Flush(void)901 int32_t FastAudioRendererSinkInner::Flush(void)
902 {
903     Trace trace("FastAudioRendererSinkInner::Flush");
904     int32_t ret;
905 
906     if (started_ && audioRender_ != nullptr) {
907         ret = audioRender_->Flush(audioRender_);
908         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
909             "Flush failed!");
910     }
911 
912     return SUCCESS;
913 }
914 
ResetOutputRouteForDisconnect(DeviceType device)915 void FastAudioRendererSinkInner::ResetOutputRouteForDisconnect(DeviceType device)
916 {
917 }
918 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)919 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],
920     const size_t size)
921 {
922     return SUCCESS;
923 }
924 
UpdateAppsUid(const std::vector<int32_t> & appsUid)925 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const std::vector<int32_t> &appsUid)
926 {
927 #ifdef FEATURE_POWER_MANAGER
928     if (!runningLockManager_) {
929         return ERROR;
930     }
931 
932     runningLockManager_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
933     runningLockManager_->UpdateAppsUidToPowerMgr();
934 #endif
935 
936     return SUCCESS;
937 }
938 
939 } // namespace AudioStandard
940 } // namespace OHOS
941