• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include <chrono>
17 #include <cstring>
18 #include <dlfcn.h>
19 #include <string>
20 #include <sstream>
21 #include <unistd.h>
22 #include <cinttypes>
23 #include "securec.h"
24 #include "audio_errors.h"
25 #include "audio_log.h"
26 #include "audio_utils.h"
27 #include "remote_audio_renderer_sink.h"
28 
29 using namespace std;
30 
31 namespace OHOS {
32 namespace AudioStandard {
33 namespace {
34 const int32_t HALF_FACTOR = 2;
35 const float DEFAULT_VOLUME_LEVEL = 1.0f;
36 const uint32_t AUDIO_CHANNELCOUNT = 2;
37 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
38 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096;
39 const uint32_t INT_32_MAX = 0x7fffffff;
40 const uint32_t PCM_8_BIT = 8;
41 const uint32_t PCM_16_BIT = 16;
42 const uint32_t INTERNAL_OUTPUT_STREAM_ID = 0;
43 constexpr int32_t PARAMS_RENDER_STATE_NUM = 2;
44 constexpr int32_t EVENT_DES_SIZE = 60;
45 constexpr int32_t RENDER_STATE_CONTENT_DES_SIZE = 60;
46 #ifdef PRODUCT_M40
47 const uint32_t PARAM_VALUE_LENTH = 20;
48 #endif
49 }
50 
51 std::map<std::string, RemoteAudioRendererSink *> RemoteAudioRendererSink::allsinks;
52 
RemoteAudioRendererSink(const std::string & deviceNetworkId)53 RemoteAudioRendererSink::RemoteAudioRendererSink(const std::string& deviceNetworkId)
54     : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
55     rightVolume_(DEFAULT_VOLUME_LEVEL), openSpeaker_(-1), audioAdapter_(nullptr),
56     audioRender_(nullptr), callback_(nullptr)
57 {
58     AUDIO_INFO_LOG("Constract.");
59     attr_ = {};
60     this->deviceNetworkId_ = deviceNetworkId;
61     audioManager_ = GetAudioManager();
62 #ifdef DEBUG_DUMP_FILE
63     pfd = nullptr;
64 #endif // DEBUG_DUMP_FILE
65 }
66 
~RemoteAudioRendererSink()67 RemoteAudioRendererSink::~RemoteAudioRendererSink()
68 {
69     if (rendererInited_ == true) {
70         RemoteAudioRendererSink::DeInit();
71     } else {
72         AUDIO_INFO_LOG("RemoteAudioRendererSink has already DeInit.");
73     }
74 }
75 
GetInstance(const char * deviceNetworkId)76 RemoteAudioRendererSink *RemoteAudioRendererSink::GetInstance(const char *deviceNetworkId)
77 {
78     AUDIO_INFO_LOG("GetInstance.");
79     RemoteAudioRendererSink *audioRenderer_ = nullptr;
80     if (deviceNetworkId == nullptr) {
81         return audioRenderer_;
82     }
83     // check if it is in our map
84     std::string deviceName = deviceNetworkId;
85     if (allsinks.count(deviceName)) {
86         return allsinks[deviceName];
87     } else {
88         audioRenderer_ = new(std::nothrow) RemoteAudioRendererSink(deviceName);
89         AUDIO_DEBUG_LOG("new Daudio device sink:[%{public}s]", deviceNetworkId);
90         allsinks[deviceName] = audioRenderer_;
91     }
92     CHECK_AND_RETURN_RET_LOG((audioRenderer_ != nullptr), nullptr, "null audioRenderer!");
93     return audioRenderer_;
94 }
95 
RegisterParameterCallback(AudioSinkCallback * callback)96 void RemoteAudioRendererSink::RegisterParameterCallback(AudioSinkCallback* callback)
97 {
98     AUDIO_INFO_LOG("RemoteAudioRendererSink: register params callback");
99     callback_ = callback;
100     if (paramCallbackRegistered_) {
101         return;
102     }
103 #ifdef PRODUCT_M40
104     // register to adapter
105     ParamCallback adapterCallback = &RemoteAudioRendererSink::ParamEventCallback;
106     if (audioAdapter_ == nullptr) {
107         AUDIO_ERR_LOG("RemoteAudioRendererSink::RegisterParameterCallback audioAdapter_ is null");
108         return;
109     }
110 
111     int32_t ret = audioAdapter_->RegExtraParamObserver(audioAdapter_, adapterCallback, this);
112     if (ret != SUCCESS) {
113         AUDIO_ERR_LOG("RemoteAudioRendererSink::RegisterParameterCallback failed, error code: %d", ret);
114     } else {
115         paramCallbackRegistered_ = true;
116     }
117 #endif
118 }
119 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)120 void RemoteAudioRendererSink::SetAudioParameter(const AudioParamKey key, const std::string& condition,
121     const std::string& value)
122 {
123 #ifdef PRODUCT_M40
124     AUDIO_INFO_LOG("RemoteAudioRendererSink::SetParameter: key %{public}d, condition: %{public}s, value: %{public}s",
125         key, condition.c_str(), value.c_str());
126     enum AudioExtParamKey hdiKey = AudioExtParamKey(key);
127     if (audioAdapter_ == nullptr) {
128         AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioParameter audioAdapter_ is null");
129         return;
130     }
131     int32_t ret = audioAdapter_->SetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value.c_str());
132     if (ret != SUCCESS) {
133         AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioParameter failed, error code: %d", ret);
134     }
135 #endif
136 }
137 
GetAudioParameter(const AudioParamKey key,const std::string & condition)138 std::string RemoteAudioRendererSink::GetAudioParameter(const AudioParamKey key, const std::string& condition)
139 {
140 #ifdef PRODUCT_M40
141     AUDIO_INFO_LOG("RemoteAudioRendererSink::GetParameter: key %{public}d, condition: %{public}s", key,
142         condition.c_str());
143     enum AudioExtParamKey hdiKey = AudioExtParamKey(key);
144     char value[PARAM_VALUE_LENTH];
145     if (audioAdapter_ == nullptr) {
146         AUDIO_ERR_LOG("RemoteAudioRendererSink::GetAudioParameter audioAdapter_ is null");
147         return "";
148     }
149     int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value, PARAM_VALUE_LENTH);
150     if (ret !=SUCCESS) {
151         AUDIO_ERR_LOG("AudioRendererSink::GetAudioParameter failed, error code: %d", ret);
152         return "";
153     }
154     return value;
155 #else
156     return "";
157 #endif
158 }
159 
ParamEventCallback(AudioExtParamKey key,const char * condition,const char * value,void * reserved,void * cookie)160 int32_t RemoteAudioRendererSink::ParamEventCallback(AudioExtParamKey key, const char* condition, const char* value,
161     void* reserved, void* cookie)
162 {
163     AUDIO_INFO_LOG("RemoteAudioRendererSink::ParamEventCallback:key:%{public}d, condition:%{public}s, value:%{public}s",
164         key, condition, value);
165     RemoteAudioRendererSink* sink = reinterpret_cast<RemoteAudioRendererSink*>(cookie);
166     std::string networkId = sink->GetNetworkId();
167     AudioParamKey audioKey = AudioParamKey(key);
168     // render state change to invalid.
169     if (audioKey == AudioParamKey::RENDER_STATE) {
170         char eventDes[EVENT_DES_SIZE];
171         char contentDes[RENDER_STATE_CONTENT_DES_SIZE];
172         if (sscanf_s(condition, "%[^;];%s", eventDes, EVENT_DES_SIZE, contentDes,
173             RENDER_STATE_CONTENT_DES_SIZE) < PARAMS_RENDER_STATE_NUM) {
174             AUDIO_ERR_LOG("[AudioPolicyServer]: Failed parse condition");
175             return 0;
176         }
177         if (!strcmp(eventDes, "ERR_EVENT")) {
178             AUDIO_INFO_LOG("RemoteAudioRendererSink render state invalid, destroy audioRender");
179             if ((sink->audioRender_ != nullptr) && (sink->audioAdapter_ != nullptr)) {
180                 sink->audioAdapter_->DestroyRender(sink->audioAdapter_, sink->audioRender_);
181             }
182             sink->audioRender_ = nullptr;
183             sink->isRenderCreated = false;
184         }
185     }
186     AudioSinkCallback* callback = sink->GetParamCallback();
187     callback->OnAudioParameterChange(networkId, audioKey, condition, value);
188     return 0;
189 }
190 
GetNetworkId()191 std::string RemoteAudioRendererSink::GetNetworkId()
192 {
193     return deviceNetworkId_;
194 }
195 
GetParamCallback()196 OHOS::AudioStandard::AudioSinkCallback* RemoteAudioRendererSink::GetParamCallback()
197 {
198     return callback_;
199 }
200 
DeInit()201 void RemoteAudioRendererSink::DeInit()
202 {
203     AUDIO_INFO_LOG("DeInit.");
204     started_ = false;
205     rendererInited_ = false;
206     if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
207         audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
208     }
209     audioRender_ = nullptr;
210 
211     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
212         if (routeHandle_ != -1) {
213             audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
214         }
215         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
216     }
217     audioAdapter_ = nullptr;
218     audioManager_ = nullptr;
219 #ifdef DEBUG_DUMP_FILE
220     if (pfd) {
221         fclose(pfd);
222         pfd = nullptr;
223     }
224 #endif // DEBUG_DUMP_FILE
225     // remove map recorder.
226     RemoteAudioRendererSink *temp = allsinks[this->deviceNetworkId_];
227     if (temp != nullptr) {
228         delete temp;
229         temp = nullptr;
230         allsinks.erase(this->deviceNetworkId_);
231     }
232 }
233 
InitAttrs(struct AudioSampleAttributes & attrs)234 void InitAttrs(struct AudioSampleAttributes &attrs)
235 {
236     /* Initialization of audio parameters for playback */
237     attrs.channelCount = AUDIO_CHANNELCOUNT;
238     attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
239     attrs.interleaved = 0;
240     attrs.streamId = INTERNAL_OUTPUT_STREAM_ID;
241     attrs.type = AUDIO_IN_MEDIA;
242     attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
243     attrs.isBigEndian = false;
244     attrs.isSignedData = true;
245     attrs.stopThreshold = INT_32_MAX;
246     attrs.silenceThreshold = 0;
247 }
248 
GetAudioManager()249 struct AudioManager *RemoteAudioRendererSink::GetAudioManager()
250 {
251     AUDIO_INFO_LOG("RemoteAudioRendererSink: Initialize audio proxy manager");
252 #ifdef PRODUCT_M40
253 #ifdef __aarch64__
254     char resolvedPath[100] = "/vendor/lib64/libdaudio_client.z.so";
255 #else
256     char resolvedPath[100] = "/vendor/lib/libdaudio_client.z.so";
257 #endif
258     struct AudioManager *(*GetAudioManagerFuncs)() = nullptr;
259 
260     void *handle_ = dlopen(resolvedPath, 1);
261     if (handle_ == nullptr) {
262         AUDIO_ERR_LOG("Open so Fail");
263         return nullptr;
264     }
265     AUDIO_INFO_LOG("dlopen successful");
266 
267     GetAudioManagerFuncs = (struct AudioManager *(*)())(dlsym(handle_, "GetAudioManagerFuncs"));
268     if (GetAudioManagerFuncs == nullptr) {
269         return nullptr;
270     }
271     AUDIO_INFO_LOG("GetAudioManagerFuncs done");
272 
273     struct AudioManager *audioManager = GetAudioManagerFuncs();
274     if (audioManager == nullptr) {
275         return nullptr;
276     }
277     AUDIO_INFO_LOG("daudio manager created");
278 #else
279     struct AudioManager *audioManager = GetAudioManagerFuncs();
280 #endif // PRODUCT_M40
281     return audioManager;
282 }
283 
CreateRender(const struct AudioPort & renderPort)284 int32_t RemoteAudioRendererSink::CreateRender(const struct AudioPort &renderPort)
285 {
286     int32_t ret;
287     int64_t start = GetNowTimeMs();
288     struct AudioSampleAttributes param;
289     InitAttrs(param);
290     param.sampleRate = attr_.sampleRate;
291     param.channelCount = attr_.channel;
292     param.format = attr_.format;
293     param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
294     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
295     AUDIO_INFO_LOG("RemoteAudioRendererSink Create render format: %{public}d", param.format);
296     struct AudioDeviceDescriptor deviceDesc;
297     deviceDesc.portId = renderPort.portId;
298     deviceDesc.pins = PIN_OUT_SPEAKER;
299     deviceDesc.desc = nullptr;
300     ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, &param, &audioRender_);
301     if (ret != 0 || audioRender_ == nullptr) {
302         AUDIO_ERR_LOG("AudioDeviceCreateRender failed");
303         return ERR_NOT_STARTED;
304     }
305 
306     isRenderCreated = true;
307     int64_t cost = GetNowTimeMs() - start;
308     AUDIO_INFO_LOG("CreateRender cost[%{public}" PRId64 "]ms", cost);
309 
310     return 0;
311 }
312 
printRemoteAttr(RemoteAudioSinkAttr attr_)313 inline std::string printRemoteAttr(RemoteAudioSinkAttr attr_)
314 {
315     std::stringstream value;
316     value << "adapterName[" << attr_.adapterName << "] openMicSpeaker[" << attr_.openMicSpeaker << "] ";
317     value << "format[" << static_cast<int32_t>(attr_.format) << "] sampleFmt[" << attr_.sampleFmt << "] ";
318     value << "sampleRate[" << attr_.sampleRate << "] channel[" << attr_.channel << "] ";
319     value << "volume[" << attr_.volume << "] filePath[" << attr_.filePath << "] ";
320     value << "deviceNetworkId[" << attr_.deviceNetworkId << "] device_type[" << attr_.device_type << "]";
321     return value.str();
322 }
323 
GetTargetAdapterPort(struct AudioAdapterDescriptor * descs,int32_t size,const char * networkId)324 int32_t RemoteAudioRendererSink::GetTargetAdapterPort(struct AudioAdapterDescriptor *descs, int32_t size,
325     const char *networkId)
326 {
327     int32_t targetIdx = -1;
328     for (int32_t index = 0; index < size; index++) {
329         struct AudioAdapterDescriptor *desc = &descs[index];
330         if (desc == nullptr || desc->adapterName == nullptr) {
331             continue;
332         }
333         if (strcmp(desc->adapterName, networkId)) {
334             AUDIO_INFO_LOG("[%{public}d] is not target adapter", index);
335             continue;
336         }
337         targetIdx = index;
338         for (uint32_t port = 0; port < desc->portNum; port++) {
339             // Only find out the port of out in the sound card
340             if (desc->ports[port].portId == PIN_OUT_SPEAKER) {
341                 audioPort_ = desc->ports[port];
342                 break;
343             }
344         }
345     }
346     return targetIdx;
347 }
348 
Init(RemoteAudioSinkAttr & attr)349 int32_t RemoteAudioRendererSink::Init(RemoteAudioSinkAttr &attr)
350 {
351     AUDIO_INFO_LOG("RemoteAudioRendererSink: Init start.");
352     attr_ = attr;
353     adapterNameCase_ = attr_.adapterName;  // Set sound card information
354     openSpeaker_ = attr_.openMicSpeaker;
355 
356     if (audioManager_ == nullptr) {
357         AUDIO_ERR_LOG("Init audio manager Fail");
358         return ERR_NOT_STARTED;
359     }
360 
361     int32_t size = 0;
362     struct AudioAdapterDescriptor *descs = nullptr;
363     int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
364     if (size == 0 || descs == nullptr || ret != 0) {
365         AUDIO_ERR_LOG("Get adapters Fail");
366         return ERR_NOT_STARTED;
367     }
368     AUDIO_INFO_LOG("Get [%{publid}d]adapters", size);
369     int32_t targetIdx = GetTargetAdapterPort(descs, size, attr_.deviceNetworkId);
370     CHECK_AND_RETURN_RET_LOG((targetIdx >= 0), ERR_NOT_STARTED, "can not find target adapter.");
371 
372     struct AudioAdapterDescriptor *desc = &descs[targetIdx];
373 
374     if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
375         AUDIO_ERR_LOG("Load Adapter Fail");
376         return ERR_NOT_STARTED;
377     }
378     if (audioAdapter_ == nullptr) {
379         AUDIO_ERR_LOG("Load audio device failed");
380         return ERR_NOT_STARTED;
381     }
382 
383     ret = audioAdapter_->InitAllPorts(audioAdapter_);
384     if (ret != 0) {
385         AUDIO_ERR_LOG("InitAllPorts failed");
386         return ERR_NOT_STARTED;
387     }
388 
389     AUDIO_INFO_LOG("RemoteAudioRendererSink: Init end.");
390     rendererInited_ = true;
391 
392 #ifdef DEBUG_DUMP_FILE
393     AUDIO_INFO_LOG("dump RemoteAudioSinkAttr:%{public}s", printRemoteAttr(attr_).c_str());
394     std::string fileName = attr_.filePath;
395     std::string filePath = "/data/local/tmp/remote_test_001.pcm";
396     const char *g_audioOutTestFilePath = filePath.c_str();
397     pfd = fopen(g_audioOutTestFilePath, "a+"); // here will not create a file if not exit.
398     AUDIO_ERR_LOG("init dump file[%{public}s]", g_audioOutTestFilePath);
399     if (pfd == nullptr) {
400         AUDIO_ERR_LOG("Error opening remote pcm file[%{public}s]", g_audioOutTestFilePath);
401     }
402 #endif // DEBUG_DUMP_FILE
403 
404     return SUCCESS;
405 }
406 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)407 int32_t RemoteAudioRendererSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
408 {
409     int64_t start = GetNowTimeMs();
410     int32_t ret;
411     if (audioRender_ == nullptr) {
412         AUDIO_ERR_LOG("Audio Render Handle is nullptr!");
413         return ERR_INVALID_HANDLE;
414     }
415 
416     ret = audioRender_->RenderFrame(audioRender_, static_cast<void*>(&data), len, &writeLen);
417     if (ret != 0) {
418         AUDIO_ERR_LOG("RenderFrame failed ret: %{public}x", ret);
419         return ERR_WRITE_FAILED;
420     }
421     writeLen = len;
422 #ifdef DEBUG_DUMP_FILE
423     if (pfd != nullptr) {
424         size_t writeResult = fwrite((void*)&data, 1, len, pfd);
425         if (writeResult != len) {
426             AUDIO_ERR_LOG("Failed to write the file.");
427         }
428     }
429 #endif // DEBUG_DUMP_FILE
430 
431     int64_t cost = GetNowTimeMs() - start;
432     AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", len, cost);
433     return SUCCESS;
434 }
435 
Start(void)436 int32_t RemoteAudioRendererSink::Start(void)
437 {
438     AUDIO_INFO_LOG("Start.");
439     if (!isRenderCreated) {
440         if (CreateRender(audioPort_) != 0) {
441             AUDIO_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
442             return ERR_NOT_STARTED;
443         }
444     }
445     int32_t ret;
446 
447     if (!started_) {
448         ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
449         if (!ret) {
450             started_ = true;
451             return SUCCESS;
452         } else {
453             AUDIO_ERR_LOG("RemoteAudioRendererSink::Start failed!");
454             return ERR_NOT_STARTED;
455         }
456     }
457     started_ = true;
458     return SUCCESS;
459 }
460 
SetVolume(float left,float right)461 int32_t RemoteAudioRendererSink::SetVolume(float left, float right)
462 {
463     int32_t ret;
464     float volume;
465 
466     if (audioRender_ == nullptr) {
467         AUDIO_ERR_LOG("RemoteAudioRendererSink::SetVolume failed audioRender_ null");
468         return ERR_INVALID_HANDLE;
469     }
470 
471     leftVolume_ = left;
472     rightVolume_ = right;
473     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
474         volume = rightVolume_;
475     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
476         volume = leftVolume_;
477     } else {
478         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
479     }
480 
481     ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
482     if (ret) {
483         AUDIO_ERR_LOG("RemoteAudioRendererSink::Set volume failed!");
484     }
485 
486     return ret;
487 }
488 
GetVolume(float & left,float & right)489 int32_t RemoteAudioRendererSink::GetVolume(float &left, float &right)
490 {
491     left = leftVolume_;
492     right = rightVolume_;
493     return SUCCESS;
494 }
495 
GetLatency(uint32_t * latency)496 int32_t RemoteAudioRendererSink::GetLatency(uint32_t *latency)
497 {
498     if (audioRender_ == nullptr) {
499         AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed audio render null");
500         return ERR_INVALID_HANDLE;
501     }
502 
503     if (!latency) {
504         AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed latency null");
505         return ERR_INVALID_PARAM;
506     }
507 
508     uint32_t hdiLatency;
509     if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
510         *latency = hdiLatency;
511         return SUCCESS;
512     } else {
513         AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed.");
514         return ERR_OPERATION_FAILED;
515     }
516     *latency = 21; // 4096 bytes ~ 21ms.
517     return SUCCESS;
518 }
519 
GetAudioCategory(AudioScene audioScene)520 static AudioCategory GetAudioCategory(AudioScene audioScene)
521 {
522     AudioCategory audioCategory;
523     switch (audioScene) {
524         case AUDIO_SCENE_DEFAULT:
525             audioCategory = AUDIO_IN_MEDIA;
526             break;
527         case AUDIO_SCENE_RINGING:
528             audioCategory = AUDIO_IN_RINGTONE;
529             break;
530         case AUDIO_SCENE_PHONE_CALL:
531             audioCategory = AUDIO_IN_CALL;
532             break;
533         case AUDIO_SCENE_PHONE_CHAT:
534             audioCategory = AUDIO_IN_COMMUNICATION;
535             break;
536         default:
537             audioCategory = AUDIO_IN_MEDIA;
538             break;
539     }
540     AUDIO_DEBUG_LOG("RemoteAudioRendererSink: Audio category returned is: %{public}d", audioCategory);
541 
542     return audioCategory;
543 }
544 
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)545 static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
546 {
547     int32_t ret = SUCCESS;
548 
549     switch (outputDevice) {
550         case DEVICE_TYPE_SPEAKER:
551             sink.ext.device.type = PIN_OUT_SPEAKER;
552             sink.ext.device.desc = "pin_out_speaker";
553             break;
554         case DEVICE_TYPE_WIRED_HEADSET:
555             sink.ext.device.type = PIN_OUT_HEADSET;
556             sink.ext.device.desc = "pin_out_headset";
557             break;
558         case DEVICE_TYPE_USB_HEADSET:
559             sink.ext.device.type = PIN_OUT_USB_EXT;
560             sink.ext.device.desc = "pin_out_usb_ext";
561             break;
562         default:
563             ret = ERR_NOT_SUPPORTED;
564             break;
565     }
566 
567     return ret;
568 }
569 
OpenOutput(DeviceType outputDevice)570 int32_t RemoteAudioRendererSink::OpenOutput(DeviceType outputDevice)
571 {
572     AudioRouteNode source = {};
573     AudioRouteNode sink = {};
574 
575     int32_t ret = SetOutputPortPin(outputDevice, sink);
576     if (ret != SUCCESS) {
577         AUDIO_ERR_LOG("RemoteAudioRendererSink: OpenOutput FAILED: %{public}d", ret);
578         return ret;
579     }
580 
581     source.portId = 0;
582     source.role = AUDIO_PORT_SOURCE_ROLE;
583     source.type = AUDIO_PORT_MIX_TYPE;
584     source.ext.mix.moduleId = 0;
585     source.ext.mix.streamId = INTERNAL_OUTPUT_STREAM_ID;
586 
587     sink.portId = audioPort_.portId;
588     sink.role = AUDIO_PORT_SINK_ROLE;
589     sink.type = AUDIO_PORT_DEVICE_TYPE;
590     sink.ext.device.moduleId = 0;
591 
592     AudioRoute route = {
593         .sourcesNum = 1,
594         .sources = &source,
595         .sinksNum = 1,
596         .sinks = &sink,
597     };
598 
599     if (audioAdapter_ == nullptr) {
600         AUDIO_ERR_LOG("OpenOutput failed, audioAdapter_ is null");
601         return ERR_INVALID_PARAM;
602     }
603     ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
604     AUDIO_DEBUG_LOG("UpdateAudioRoute returns: %{public}d", ret);
605     if (ret != 0) {
606         AUDIO_ERR_LOG("UpdateAudioRoute failed");
607         return ERR_OPERATION_FAILED;
608     }
609 
610     return SUCCESS;
611 }
612 
SetAudioScene(AudioScene audioScene)613 int32_t RemoteAudioRendererSink::SetAudioScene(AudioScene audioScene)
614 {
615     AUDIO_INFO_LOG("RemoteAudioRendererSink::SetAudioScene in");
616     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene <= AUDIO_SCENE_PHONE_CHAT,
617         ERR_INVALID_PARAM, "invalid audioScene");
618     if (audioRender_ == nullptr) {
619         AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioScene failed audio render handle is null!");
620         return ERR_INVALID_HANDLE;
621     }
622 
623     int32_t ret = OpenOutput(DEVICE_TYPE_SPEAKER);
624     if (ret < 0) {
625         AUDIO_ERR_LOG("RemoteAudioRendererSink: Update route FAILED: %{public}d", ret);
626     }
627     struct AudioSceneDescriptor scene;
628     scene.scene.id = GetAudioCategory(audioScene);
629     scene.desc.pins = PIN_OUT_SPEAKER;
630     if (audioRender_->scene.SelectScene == nullptr) {
631         AUDIO_ERR_LOG("RemoteAudioRendererSink: Select scene nullptr");
632         return ERR_OPERATION_FAILED;
633     }
634 
635     AUDIO_INFO_LOG("RemoteAudioRendererSink::SelectScene start");
636     ret = audioRender_->scene.SelectScene((AudioHandle)audioRender_, &scene);
637     AUDIO_INFO_LOG("RemoteAudioRendererSink::SelectScene over");
638     if (ret < 0) {
639         AUDIO_ERR_LOG("RemoteAudioRendererSink: Select scene FAILED: %{public}d", ret);
640         return ERR_OPERATION_FAILED;
641     }
642 
643     AUDIO_INFO_LOG("RemoteAudioRendererSink::Select audio scene SUCCESS: %{public}d", audioScene);
644     return SUCCESS;
645 }
646 
Stop(void)647 int32_t RemoteAudioRendererSink::Stop(void)
648 {
649     AUDIO_INFO_LOG("Stop.");
650     int32_t ret;
651 
652     if (audioRender_ == nullptr) {
653         AUDIO_ERR_LOG("RemoteAudioRendererSink::Stop failed audioRender_ null");
654         return ERR_INVALID_HANDLE;
655     }
656 
657     if (started_) {
658         ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
659         if (!ret) {
660             started_ = false;
661             return SUCCESS;
662         } else {
663             AUDIO_ERR_LOG("RemoteAudioRendererSink::Stop failed!");
664             return ERR_OPERATION_FAILED;
665         }
666     }
667     started_ = false;
668     return SUCCESS;
669 }
670 
Pause(void)671 int32_t RemoteAudioRendererSink::Pause(void)
672 {
673     AUDIO_INFO_LOG("Pause.");
674     int32_t ret;
675 
676     if (audioRender_ == nullptr) {
677         AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause failed audioRender_ null");
678         return ERR_INVALID_HANDLE;
679     }
680 
681     if (!started_) {
682         AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause invalid state!");
683         return ERR_OPERATION_FAILED;
684     }
685 
686     if (!paused_) {
687         ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
688         if (!ret) {
689             paused_ = true;
690             return SUCCESS;
691         } else {
692             AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause failed!");
693             return ERR_OPERATION_FAILED;
694         }
695     }
696     return SUCCESS;
697 }
698 
Resume(void)699 int32_t RemoteAudioRendererSink::Resume(void)
700 {
701     AUDIO_INFO_LOG("Pause.");
702     int32_t ret;
703 
704     if (audioRender_ == nullptr) {
705         AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume failed audioRender_ null");
706         return ERR_INVALID_HANDLE;
707     }
708 
709     if (!started_) {
710         AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume invalid state!");
711         return ERR_OPERATION_FAILED;
712     }
713 
714     if (paused_) {
715         ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
716         if (!ret) {
717             paused_ = false;
718             return SUCCESS;
719         } else {
720             AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume failed!");
721             return ERR_OPERATION_FAILED;
722         }
723     }
724     return SUCCESS;
725 }
726 
Reset(void)727 int32_t RemoteAudioRendererSink::Reset(void)
728 {
729     AUDIO_INFO_LOG("Reset.");
730     int32_t ret;
731 
732     if (started_ && audioRender_ != nullptr) {
733         ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
734         if (!ret) {
735             return SUCCESS;
736         } else {
737             AUDIO_ERR_LOG("RemoteAudioRendererSink::Reset failed!");
738             return ERR_OPERATION_FAILED;
739         }
740     }
741     return ERR_OPERATION_FAILED;
742 }
743 
Flush(void)744 int32_t RemoteAudioRendererSink::Flush(void)
745 {
746     AUDIO_INFO_LOG("Flush.");
747     int32_t ret;
748 
749     if (started_ && audioRender_ != nullptr) {
750         ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
751         if (!ret) {
752             return SUCCESS;
753         } else {
754             AUDIO_ERR_LOG("RemoteAudioRendererSink::Flush failed!");
755             return ERR_OPERATION_FAILED;
756         }
757     }
758     return ERR_OPERATION_FAILED;
759 }
760 } // namespace AudioStandard
761 } // namespace OHOS
762 
763 #ifdef __cplusplus
764 extern "C" {
765 #endif
766 
767 using namespace OHOS::AudioStandard;
768 
FillinRemoteAudioRenderSinkWapper(const char * deviceNetworkId,void ** wapper)769 int32_t FillinRemoteAudioRenderSinkWapper(const char *deviceNetworkId, void **wapper)
770 {
771     RemoteAudioRendererSink *instance = RemoteAudioRendererSink::GetInstance(deviceNetworkId);
772     if (instance != nullptr) {
773         *wapper = static_cast<void *>(instance);
774     } else {
775         *wapper = nullptr;
776     }
777 
778     return SUCCESS;
779 }
780 
RemoteAudioRendererSinkInit(void * wapper,RemoteAudioSinkAttr * attr)781 int32_t RemoteAudioRendererSinkInit(void *wapper, RemoteAudioSinkAttr *attr)
782 {
783     int32_t ret;
784     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
785     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
786     if (audioRendererSink->rendererInited_)
787         return SUCCESS;
788 
789     ret = audioRendererSink->Init(*attr);
790     return ret;
791 }
792 
RemoteAudioRendererSinkDeInit(void * wapper)793 void RemoteAudioRendererSinkDeInit(void *wapper)
794 {
795     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
796     CHECK_AND_RETURN_LOG(audioRendererSink != nullptr, "null audioRendererSink");
797     // remove the sink in allsinks.
798     if (audioRendererSink->rendererInited_)
799         audioRendererSink->DeInit();
800 }
801 
RemoteAudioRendererSinkStop(void * wapper)802 int32_t RemoteAudioRendererSinkStop(void *wapper)
803 {
804     int32_t ret;
805     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
806     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
807     if (!audioRendererSink->rendererInited_)
808         return SUCCESS;
809 
810     ret = audioRendererSink->Stop();
811     return ret;
812 }
813 
RemoteAudioRendererSinkStart(void * wapper)814 int32_t RemoteAudioRendererSinkStart(void *wapper)
815 {
816     int32_t ret;
817     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
818     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
819     if (!audioRendererSink->rendererInited_) {
820         AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
821         return ERR_NOT_STARTED;
822     }
823 
824     ret = audioRendererSink->Start();
825     return ret;
826 }
827 
RemoteAudioRendererSinkPause(void * wapper)828 int32_t RemoteAudioRendererSinkPause(void *wapper)
829 {
830     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
831     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
832     if (!audioRendererSink->rendererInited_) {
833         AUDIO_ERR_LOG("Renderer pause failed");
834         return ERR_NOT_STARTED;
835     }
836 
837     return audioRendererSink->Pause();
838 }
839 
RemoteAudioRendererSinkResume(void * wapper)840 int32_t RemoteAudioRendererSinkResume(void *wapper)
841 {
842     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
843     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
844     if (!audioRendererSink->rendererInited_) {
845         AUDIO_ERR_LOG("Renderer resume failed");
846         return ERR_NOT_STARTED;
847     }
848 
849     return audioRendererSink->Resume();
850 }
851 
RemoteAudioRendererRenderFrame(void * wapper,char & data,uint64_t len,uint64_t & writeLen)852 int32_t RemoteAudioRendererRenderFrame(void *wapper, char &data, uint64_t len, uint64_t &writeLen)
853 {
854     int32_t ret;
855     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
856     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
857     if (!audioRendererSink->rendererInited_) {
858         AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
859         return ERR_NOT_STARTED;
860     }
861 
862     ret = audioRendererSink->RenderFrame(data, len, writeLen);
863     return ret;
864 }
865 
RemoteAudioRendererSinkSetVolume(void * wapper,float left,float right)866 int32_t RemoteAudioRendererSinkSetVolume(void *wapper, float left, float right)
867 {
868     int32_t ret;
869     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
870     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
871     if (!audioRendererSink->rendererInited_) {
872         AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
873         return ERR_NOT_STARTED;
874     }
875 
876     ret = audioRendererSink->SetVolume(left, right);
877     return ret;
878 }
879 
RemoteAudioRendererSinkGetLatency(void * wapper,uint32_t * latency)880 int32_t RemoteAudioRendererSinkGetLatency(void *wapper, uint32_t *latency)
881 {
882     int32_t ret;
883     RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
884     CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
885     if (!audioRendererSink->rendererInited_) {
886         AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
887         return ERR_NOT_STARTED;
888     }
889 
890     if (!latency) {
891         AUDIO_ERR_LOG("RemoteAudioRendererSinkGetLatency failed latency null");
892         return ERR_INVALID_PARAM;
893     }
894 
895     ret = audioRendererSink->GetLatency(latency);
896     return ret;
897 }
898 
RemoteAudioRendererSinkGetTransactionId(uint64_t * transactionId)899 int32_t RemoteAudioRendererSinkGetTransactionId(uint64_t *transactionId)
900 {
901     // as we can not get wapper initialized, we dont know which sink address we should return.
902     *transactionId = static_cast<uint16_t>(-1);
903     return SUCCESS;
904 }
905 #ifdef __cplusplus
906 }
907 #endif
908