• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dspeaker_dev.h"
17 
18 #include <algorithm>
19 #include <condition_variable>
20 #include <mutex>
21 #include <string>
22 #include <thread>
23 #include <securec.h>
24 
25 #include "daudio_constants.h"
26 #include "daudio_errorcode.h"
27 #include "daudio_hidumper.h"
28 #include "daudio_hisysevent.h"
29 #include "daudio_hitrace.h"
30 #include "daudio_log.h"
31 #include "daudio_radar.h"
32 #include "daudio_source_manager.h"
33 #include "daudio_util.h"
34 
35 #undef DH_LOG_TAG
36 #define DH_LOG_TAG "DSpeakerDev"
37 
38 namespace OHOS {
39 namespace DistributedHardware {
EnableDevice(const int32_t dhId,const std::string & capability)40 int32_t DSpeakerDev::EnableDevice(const int32_t dhId, const std::string &capability)
41 {
42     DHLOGI("Enable IO device, device pin: %{public}d.", dhId);
43     int32_t ret = DAudioHdiHandler::GetInstance().RegisterAudioDevice(devId_, dhId, capability, shared_from_this());
44     if (ret != DH_SUCCESS) {
45         DHLOGE("Register device failed, ret: %{public}d.", ret);
46         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_REGISTER_FAIL, devId_, std::to_string(dhId), ret,
47             "daudio register device failed.");
48         return ret;
49     }
50     dhId_ = dhId;
51     auto pos = capability.find(SUB_PROTOCOLVER);
52     if (pos != std::string::npos) {
53         DHLOGD("ProtocolVer : 2.0");
54     } else {
55         isNeedCodec_.store(false);
56         DHLOGD("ProtocolVer : 1.0");
57     }
58     return DH_SUCCESS;
59 }
60 
DisableDevice(const int32_t dhId)61 int32_t DSpeakerDev::DisableDevice(const int32_t dhId)
62 {
63     DHLOGI("Disable IO device, device pin: %{public}d.", dhId);
64     int32_t ret = DAudioHdiHandler::GetInstance().UnRegisterAudioDevice(devId_, dhId);
65     if (ret != DH_SUCCESS) {
66         DHLOGE("UnRegister failed, ret: %{public}d.", ret);
67         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_UNREGISTER_FAIL, devId_, std::to_string(dhId), ret,
68             "daudio unregister device failed.");
69         return ret;
70     }
71     return DH_SUCCESS;
72 }
73 
InitReceiverEngine(IAVEngineProvider * providerPtr)74 int32_t DSpeakerDev::InitReceiverEngine(IAVEngineProvider *providerPtr)
75 {
76     DHLOGI("InitReceiverEngine enter.");
77     return DH_SUCCESS;
78 }
79 
InitSenderEngine(IAVEngineProvider * providerPtr)80 int32_t DSpeakerDev::InitSenderEngine(IAVEngineProvider *providerPtr)
81 {
82     DHLOGI("InitSenderEngine enter");
83     if (speakerTrans_ == nullptr) {
84         speakerTrans_ = std::make_shared<AVTransSenderTransport>(devId_, shared_from_this());
85     }
86     int32_t ret = speakerTrans_->InitEngine(providerPtr);
87     if (ret != DH_SUCCESS) {
88         DHLOGE("Speaker dev initialize av sender adapter failed.");
89         return ret;
90     }
91     return ret;
92 }
93 
InitCtrlTrans()94 int32_t DSpeakerDev::InitCtrlTrans()
95 {
96     DHLOGI("InitCtrlTrans enter");
97     if (speakerCtrlTrans_ == nullptr) {
98         speakerCtrlTrans_ = std::make_shared<DaudioSourceCtrlTrans>(devId_,
99             SESSIONNAME_SPK_SOURCE, SESSIONNAME_SPK_SINK, shared_from_this());
100     }
101     int32_t ret = speakerCtrlTrans_->SetUp(shared_from_this());
102     CHECK_AND_RETURN_RET_LOG(ret != DH_SUCCESS, ret, "Speaker ctrl SetUp failed.");
103     ret = speakerCtrlTrans_->Start();
104     CHECK_AND_RETURN_RET_LOG(ret != DH_SUCCESS, ret, "Speaker ctrl Start failed.");
105     return ret;
106 }
107 
OnCtrlTransEvent(const AVTransEvent & event)108 void DSpeakerDev::OnCtrlTransEvent(const AVTransEvent &event)
109 {
110     if (event.type == EventType::EVENT_START_SUCCESS) {
111         OnStateChange(DATA_OPENED);
112     } else if ((event.type == EventType::EVENT_STOP_SUCCESS) ||
113         (event.type == EventType::EVENT_CHANNEL_CLOSED) ||
114         (event.type == EventType::EVENT_START_FAIL)) {
115         OnStateChange(DATA_CLOSED);
116     }
117 }
118 
OnCtrlTransMessage(const std::shared_ptr<AVTransMessage> & message)119 void DSpeakerDev::OnCtrlTransMessage(const std::shared_ptr<AVTransMessage> &message)
120 {
121     CHECK_NULL_VOID(message);
122     DHLOGI("On Engine message, type : %{public}s.", GetEventNameByType(message->type_).c_str());
123     DAudioSourceManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_,
124         message->type_, message->content_);
125 }
126 
OnEngineTransEvent(const AVTransEvent & event)127 void DSpeakerDev::OnEngineTransEvent(const AVTransEvent &event)
128 {
129     if (event.type == EventType::EVENT_START_SUCCESS) {
130         OnStateChange(DATA_OPENED);
131     } else if ((event.type == EventType::EVENT_STOP_SUCCESS) ||
132         (event.type == EventType::EVENT_CHANNEL_CLOSED) ||
133         (event.type == EventType::EVENT_START_FAIL)) {
134         OnStateChange(DATA_CLOSED);
135     }
136 }
137 
OnEngineTransMessage(const std::shared_ptr<AVTransMessage> & message)138 void DSpeakerDev::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message)
139 {
140     CHECK_NULL_VOID(message);
141     DHLOGI("On Engine message, type : %{public}s.", GetEventNameByType(message->type_).c_str());
142     DAudioSourceManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_,
143         message->type_, message->content_);
144 }
145 
CreateStream(const int32_t streamId)146 int32_t DSpeakerDev::CreateStream(const int32_t streamId)
147 {
148     DHLOGI("Open stream of speaker device, streamId: %{public}d.", streamId);
149     std::shared_ptr<IAudioEventCallback> cbObj = audioEventCallback_.lock();
150     CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR);
151 
152     cJSON *jParam = cJSON_CreateObject();
153     CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
154     cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
155     char *jsonData = cJSON_PrintUnformatted(jParam);
156     if (jsonData == nullptr) {
157         DHLOGE("Failed to create JSON data.");
158         cJSON_Delete(jParam);
159         return ERR_DH_AUDIO_NULLPTR;
160     }
161     std::string jsonDataStr(jsonData);
162     AudioEvent event(AudioEventType::OPEN_SPEAKER, jsonDataStr);
163     cbObj->NotifyEvent(event);
164     DAudioHisysevent::GetInstance().SysEventWriteBehavior(DAUDIO_OPEN, devId_, std::to_string(dhId_),
165         "daudio spk device open success.");
166     streamId_ = streamId;
167     cJSON_Delete(jParam);
168     cJSON_free(jsonData);
169     DaudioRadar::GetInstance().ReportSpeakerOpen("CreateStream", SpeakerOpen::CREATE_STREAM,
170         BizState::BIZ_STATE_START, DH_SUCCESS);
171     return DH_SUCCESS;
172 }
173 
DestroyStream(const int32_t streamId)174 int32_t DSpeakerDev::DestroyStream(const int32_t streamId)
175 {
176     DHLOGI("Close stream of speaker device streamId: %{public}d.",  streamId);
177     std::shared_ptr<IAudioEventCallback> cbObj = audioEventCallback_.lock();
178     CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR);
179 
180     cJSON *jParam = cJSON_CreateObject();
181     CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
182     cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
183     char *jsonData = cJSON_PrintUnformatted(jParam);
184     if (jsonData == nullptr) {
185         DHLOGE("Failed to create JSON data.");
186         cJSON_Delete(jParam);
187         return ERR_DH_AUDIO_NULLPTR;
188     }
189     std::string jsonDataStr(jsonData);
190     AudioEvent event(AudioEventType::CLOSE_SPEAKER, jsonDataStr);
191     cbObj->NotifyEvent(event);
192     DAudioHisysevent::GetInstance().SysEventWriteBehavior(DAUDIO_CLOSE, devId_, std::to_string(dhId_),
193         "daudio spk device close success.");
194     curPort_ = 0;
195     cJSON_Delete(jParam);
196     cJSON_free(jsonData);
197     DaudioRadar::GetInstance().ReportSpeakerClose("DestroyStream", SpeakerClose::DESTROY_STREAM,
198         BizState::BIZ_STATE_START, DH_SUCCESS);
199     return DH_SUCCESS;
200 }
201 
SetParameters(const int32_t streamId,const AudioParamHDF & param)202 int32_t DSpeakerDev::SetParameters(const int32_t streamId, const AudioParamHDF &param)
203 {
204     DHLOGD("Set speaker parameters {samplerate: %{public}d, channelmask: %{public}d, format: %{public}d, "
205         "streamusage: %{public}d, period: %{public}d, framesize: %{public}d, renderFlags: %{public}d, "
206         "ext{%{public}s}}.", param.sampleRate, param.channelMask, param.bitFormat, param.streamUsage,
207         param.period, param.frameSize, param.renderFlags, param.ext.c_str());
208     curPort_ = dhId_;
209     paramHDF_ = param;
210 
211     param_.comParam.sampleRate = paramHDF_.sampleRate;
212     param_.comParam.channelMask = paramHDF_.channelMask;
213     param_.comParam.bitFormat = paramHDF_.bitFormat;
214     param_.comParam.codecType = AudioCodecType::AUDIO_CODEC_AAC;
215     param_.comParam.frameSize = paramHDF_.frameSize;
216     param_.renderOpts.contentType = CONTENT_TYPE_MUSIC;
217     param_.renderOpts.renderFlags = paramHDF_.renderFlags;
218     param_.renderOpts.streamUsage = paramHDF_.streamUsage;
219     if (isNeedCodec_.load()) {
220         param_.comParam.codecType = AudioCodecType::AUDIO_CODEC_AAC_EN;
221     }
222     DHLOGD("isNeedCodec_: %{public}d", isNeedCodec_.load());
223     return DH_SUCCESS;
224 }
225 
NotifyEvent(const int32_t streamId,const AudioEvent & event)226 int32_t DSpeakerDev::NotifyEvent(const int32_t streamId, const AudioEvent &event)
227 {
228     DHLOGD("Notify speaker event.");
229     std::shared_ptr<IAudioEventCallback> cbObj = audioEventCallback_.lock();
230     CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR);
231     AudioEvent audioEvent(event.type, event.content);
232     cbObj->NotifyEvent(audioEvent);
233     return DH_SUCCESS;
234 }
235 
SetUp()236 int32_t DSpeakerDev::SetUp()
237 {
238     DHLOGI("Set up speaker device.");
239     CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
240 
241     int32_t ret = speakerTrans_->SetUp(param_, param_, shared_from_this(), CAP_SPK);
242     if (ret != DH_SUCCESS) {
243         DHLOGE("Speaker trans set up failed. ret:%{public}d", ret);
244         return ret;
245     }
246     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, SPK_DEV_FILENAME, &dumpFileCommn_);
247     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, SPK_LOWLATENCY_FILENAME, &dumpFileFast_);
248     return DH_SUCCESS;
249 }
250 
Start()251 int32_t DSpeakerDev::Start()
252 {
253     DHLOGI("Start speaker device.");
254     CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
255     int32_t ret = speakerTrans_->Start();
256     DaudioRadar::GetInstance().ReportSpeakerOpenProgress("Start", SpeakerOpen::TRANS_START, ret);
257     if (ret != DH_SUCCESS) {
258         DHLOGE("Speaker trans start failed, ret: %{public}d.", ret);
259         return ret;
260     }
261     std::unique_lock<std::mutex> lck(channelWaitMutex_);
262     auto status = channelWaitCond_.wait_for(lck, std::chrono::seconds(CHANNEL_WAIT_SECONDS),
263         [this]() { return isTransReady_.load(); });
264     if (!status) {
265         DHLOGE("Wait channel open timeout(%{public}ds).", CHANNEL_WAIT_SECONDS);
266         return ERR_DH_AUDIO_SA_WAIT_TIMEOUT;
267     }
268     isOpened_.store(true);
269     return DH_SUCCESS;
270 }
271 
Stop()272 int32_t DSpeakerDev::Stop()
273 {
274     DHLOGI("Stop speaker device.");
275     CHECK_NULL_RETURN(speakerTrans_, DH_SUCCESS);
276     isOpened_.store(false);
277     isTransReady_.store(false);
278     int32_t ret = speakerTrans_->Stop();
279     DaudioRadar::GetInstance().ReportSpeakerCloseProgress("Stop", SpeakerClose::STOP_TRANS, ret);
280     if (ret != DH_SUCCESS) {
281         DHLOGE("Stop speaker trans failed, ret: %{public}d.", ret);
282         return ret;
283     }
284     return DH_SUCCESS;
285 }
286 
Release()287 int32_t DSpeakerDev::Release()
288 {
289     DHLOGI("Release speaker device.");
290     if (ashmem_ != nullptr) {
291         ashmem_->UnmapAshmem();
292         ashmem_->CloseAshmem();
293         ashmem_ = nullptr;
294         DHLOGI("UnInit ashmem success.");
295     }
296     if (speakerCtrlTrans_ != nullptr) {
297         int32_t res = speakerCtrlTrans_->Release();
298         CHECK_AND_RETURN_RET_LOG(res != DH_SUCCESS, res, "Speaker ctrl Release failed.");
299     }
300     CHECK_NULL_RETURN(speakerTrans_, DH_SUCCESS);
301     int32_t ret = speakerTrans_->Release();
302     DaudioRadar::GetInstance().ReportSpeakerCloseProgress("Release", SpeakerClose::RELEASE_TRANS, ret);
303     if (ret != DH_SUCCESS) {
304         DHLOGE("Release speaker trans failed, ret: %{public}d.", ret);
305     }
306     DumpFileUtil::CloseDumpFile(&dumpFileCommn_);
307     DumpFileUtil::CloseDumpFile(&dumpFileFast_);
308     return DH_SUCCESS;
309 }
310 
Pause()311 int32_t DSpeakerDev::Pause()
312 {
313     DHLOGI("Pause.");
314     CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
315     int32_t ret = speakerTrans_->Pause();
316     if (ret != DH_SUCCESS) {
317         DHLOGE("Pause speaker trans failed, ret: %{public}d.", ret);
318         return ret;
319     }
320     DHLOGD("Pause success.");
321     return DH_SUCCESS;
322 }
323 
Restart()324 int32_t DSpeakerDev::Restart()
325 {
326     DHLOGI("Restart.");
327     CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
328     int32_t ret = speakerTrans_->Restart(param_, param_);
329     if (ret != DH_SUCCESS) {
330         DHLOGE("Restart speaker trans failed, ret: %{public}d.", ret);
331         return ret;
332     }
333     DHLOGD("Restart success.");
334     return DH_SUCCESS;
335 }
336 
IsOpened()337 bool DSpeakerDev::IsOpened()
338 {
339     return isOpened_.load();
340 }
341 
ReadStreamData(const int32_t streamId,std::shared_ptr<AudioData> & data)342 int32_t DSpeakerDev::ReadStreamData(const int32_t streamId, std::shared_ptr<AudioData> &data)
343 {
344     (void)streamId;
345     (void)data;
346     DHLOGD("Dspeaker dev not support read stream data.");
347     return DH_SUCCESS;
348 }
349 
WriteStreamData(const int32_t streamId,std::shared_ptr<AudioData> & data)350 int32_t DSpeakerDev::WriteStreamData(const int32_t streamId, std::shared_ptr<AudioData> &data)
351 {
352     DHLOGD("Write stream data, streamId:%{public}d", streamId);
353     int64_t startTime = GetNowTimeUs();
354     CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
355     CHECK_NULL_RETURN(data, ERR_DH_AUDIO_NULLPTR);
356     DumpFileUtil::WriteDumpFile(dumpFileCommn_, static_cast<void *>(data->Data()), data->Size());
357     int32_t ret = speakerTrans_->FeedAudioData(data);
358     if (ret != DH_SUCCESS) {
359         DHLOGE("Write stream data failed, ret: %{public}d.", ret);
360         return ret;
361     }
362     int64_t endTime = GetNowTimeUs();
363     if (IsOutDurationRange(startTime, endTime, lastwriteStartTime_)) {
364         DHLOGE("This time write data spend: %{public}" PRId64" us, The interval of write data this time and "
365             "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastwriteStartTime_);
366     }
367     lastwriteStartTime_ = startTime;
368     return DH_SUCCESS;
369 }
370 
ReadMmapPosition(const int32_t streamId,uint64_t & frames,CurrentTimeHDF & time)371 int32_t DSpeakerDev::ReadMmapPosition(const int32_t streamId,
372     uint64_t &frames, CurrentTimeHDF &time)
373 {
374     DHLOGD("Read mmap position. frames: %{public}" PRIu64", tvsec: %{public}" PRId64", tvNSec:%{public}" PRId64,
375         readNum_, readTvSec_, readTvNSec_);
376     frames = readNum_;
377     time.tvSec = readTvSec_;
378     time.tvNSec = readTvNSec_;
379     return DH_SUCCESS;
380 }
381 
RefreshAshmemInfo(const int32_t streamId,int32_t fd,int32_t ashmemLength,int32_t lengthPerTrans)382 int32_t DSpeakerDev::RefreshAshmemInfo(const int32_t streamId,
383     int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans)
384 {
385     DHLOGD("RefreshAshmemInfo: fd:%{public}d, ashmemLength: %{public}d, lengthPerTrans: %{public}d",
386         fd, ashmemLength, lengthPerTrans);
387     if (param_.renderOpts.renderFlags == MMAP_MODE) {
388         DHLOGI("DSpeaker dev low-latency mode");
389         if (ashmem_ != nullptr) {
390             return DH_SUCCESS;
391         }
392         if (ashmemLength < ASHMEM_MAX_LEN) {
393             ashmem_ = sptr<Ashmem>(new Ashmem(fd, ashmemLength));
394             ashmemLength_ = ashmemLength;
395             lengthPerTrans_ = lengthPerTrans;
396             DHLOGI("Create ashmem success. fd:%{public}d, ashmem length: %{public}d, lengthPreTrans: %{public}d",
397                 fd, ashmemLength_, lengthPerTrans_);
398             bool mapRet = ashmem_->MapReadAndWriteAshmem();
399             if (!mapRet) {
400                 DHLOGE("Mmap ashmem failed.");
401                 return ERR_DH_AUDIO_NULLPTR;
402             }
403         }
404     }
405     return DH_SUCCESS;
406 }
407 
MmapStart()408 int32_t DSpeakerDev::MmapStart()
409 {
410     CHECK_NULL_RETURN(ashmem_, ERR_DH_AUDIO_NULLPTR);
411     isEnqueueRunning_.store(true);
412     enqueueDataThread_ = std::thread([this]() { this->EnqueueThread(); });
413     if (pthread_setname_np(enqueueDataThread_.native_handle(), ENQUEUE_THREAD) != DH_SUCCESS) {
414         DHLOGE("Enqueue data thread setname failed.");
415     }
416     return DH_SUCCESS;
417 }
418 
EnqueueThread()419 void DSpeakerDev::EnqueueThread()
420 {
421     readIndex_ = 0;
422     readNum_ = 0;
423     frameIndex_ = 0;
424     int64_t timeIntervalns = static_cast<int64_t>(paramHDF_.period * AUDIO_NS_PER_SECOND / AUDIO_MS_PER_SECOND);
425     DHLOGI("Enqueue thread start, lengthPerRead length: %{public}d, interval: %{pubic}d.", lengthPerTrans_,
426         paramHDF_.period);
427     while (ashmem_ != nullptr && isEnqueueRunning_.load()) {
428         int64_t timeOffset = UpdateTimeOffset(frameIndex_, timeIntervalns, startTime_);
429         DHLOGD("Read frameIndex: %{public}" PRId64", timeOffset: %{public}" PRId64, frameIndex_, timeOffset);
430         auto readData = ashmem_->ReadFromAshmem(lengthPerTrans_, readIndex_);
431         DHLOGD("Read from ashmem success! read index: %{public}d, readLength: %{public}d.",
432             readIndex_, lengthPerTrans_);
433         std::shared_ptr<AudioData> audioData = std::make_shared<AudioData>(lengthPerTrans_);
434         if (readData != nullptr) {
435             const uint8_t *readAudioData = reinterpret_cast<const uint8_t *>(readData);
436             if (memcpy_s(audioData->Data(), audioData->Capacity(), readAudioData, param_.comParam.frameSize) != EOK) {
437                 DHLOGE("Copy audio data failed.");
438             }
439         }
440         CHECK_NULL_VOID(speakerTrans_);
441         DumpFileUtil::WriteDumpFile(dumpFileFast_, static_cast<void *>(audioData->Data()), audioData->Size());
442         int32_t ret = speakerTrans_->FeedAudioData(audioData);
443         if (ret != DH_SUCCESS) {
444             DHLOGE("Speaker enqueue thread, write stream data failed, ret: %{public}d.", ret);
445         }
446         readIndex_ += lengthPerTrans_;
447         if (readIndex_ >= ashmemLength_) {
448             readIndex_ = 0;
449         }
450         readNum_ += static_cast<uint64_t>(CalculateSampleNum(param_.comParam.sampleRate, paramHDF_.period));
451         GetCurrentTime(readTvSec_, readTvNSec_);
452         frameIndex_++;
453         AbsoluteSleep(startTime_ + frameIndex_ * timeIntervalns - timeOffset);
454     }
455 }
456 
MmapStop()457 int32_t DSpeakerDev::MmapStop()
458 {
459     isEnqueueRunning_.store(false);
460     if (enqueueDataThread_.joinable()) {
461         enqueueDataThread_.join();
462     }
463     DHLOGI("Spk mmap stop end.");
464     return DH_SUCCESS;
465 }
466 
GetAudioParam() const467 AudioParam DSpeakerDev::GetAudioParam() const
468 {
469     return param_;
470 }
471 
SendMessage(uint32_t type,std::string content,std::string dstDevId)472 int32_t DSpeakerDev::SendMessage(uint32_t type, std::string content, std::string dstDevId)
473 {
474     DHLOGD("Send message to remote.");
475     if (type != static_cast<uint32_t>(OPEN_SPEAKER) && type != static_cast<uint32_t>(CLOSE_SPEAKER) &&
476         type != static_cast<uint32_t>(CHANGE_PLAY_STATUS) && type != static_cast<uint32_t>(VOLUME_SET) &&
477         type != static_cast<uint32_t>(VOLUME_MUTE_SET)) {
478         DHLOGE("Send message to remote. not OPEN_SPK or CLOSE_SPK. type: %{public}u", type);
479         return ERR_DH_AUDIO_NULLPTR;
480     }
481     CHECK_NULL_RETURN(speakerCtrlTrans_, ERR_DH_AUDIO_NULLPTR);
482     speakerCtrlTrans_->SendAudioEvent(type, content, dstDevId);
483     return DH_SUCCESS;
484 }
485 
NotifyHdfAudioEvent(const AudioEvent & event,const int32_t portId)486 int32_t DSpeakerDev::NotifyHdfAudioEvent(const AudioEvent &event, const int32_t portId)
487 {
488     int32_t ret = DAudioHdiHandler::GetInstance().NotifyEvent(devId_, portId, streamId_, event);
489     if (ret != DH_SUCCESS) {
490         DHLOGE("Notify event: %{public}d, result: %{public}s, streamId: %{public}d.",
491             event.type, event.content.c_str(), streamId_);
492     }
493     return DH_SUCCESS;
494 }
495 
OnStateChange(const AudioEventType type)496 int32_t DSpeakerDev::OnStateChange(const AudioEventType type)
497 {
498     DHLOGI("On speaker device state change, type: %{public}d.", type);
499     AudioEvent event;
500     switch (type) {
501         case AudioEventType::DATA_OPENED:
502             isTransReady_.store(true);
503             channelWaitCond_.notify_all();
504             event.type = AudioEventType::SPEAKER_OPENED;
505             break;
506         case AudioEventType::DATA_CLOSED:
507             isOpened_.store(false);
508             isTransReady_.store(false);
509             event.type = AudioEventType::SPEAKER_CLOSED;
510             break;
511         default:
512             break;
513     }
514     event.content = GetCJsonString(KEY_DH_ID, std::to_string(dhId_).c_str());
515     std::shared_ptr<IAudioEventCallback> cbObj = audioEventCallback_.lock();
516     CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR);
517     cbObj->NotifyEvent(event);
518     return DH_SUCCESS;
519 }
520 
OnDecodeTransDataDone(const std::shared_ptr<AudioData> & audioData)521 int32_t DSpeakerDev::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData)
522 {
523     (void) audioData;
524     return DH_SUCCESS;
525 }
526 } // DistributedHardware
527 } // OHOS
528