• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "dspeaker_client.h"
17 
18 #include "daudio_constants.h"
19 #include "daudio_hisysevent.h"
20 #include "daudio_util.h"
21 #include "daudio_sink_manager.h"
22 
23 #undef DH_LOG_TAG
24 #define DH_LOG_TAG "DSpeakerClient"
25 
26 namespace OHOS {
27 namespace DistributedHardware {
~DSpeakerClient()28 DSpeakerClient::~DSpeakerClient()
29 {
30     DHLOGD("Release speaker client.");
31 }
32 
OnEngineTransEvent(const AVTransEvent & event)33 void DSpeakerClient::OnEngineTransEvent(const AVTransEvent &event)
34 {
35     if (event.type == EventType::EVENT_START_SUCCESS) {
36         OnStateChange(DATA_OPENED);
37     } else if ((event.type == EventType::EVENT_STOP_SUCCESS) ||
38         (event.type == EventType::EVENT_CHANNEL_CLOSED) ||
39         (event.type == EventType::EVENT_START_FAIL)) {
40         OnStateChange(DATA_CLOSED);
41     }
42 }
43 
OnEngineTransMessage(const std::shared_ptr<AVTransMessage> & message)44 void DSpeakerClient::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message)
45 {
46     if (message == nullptr) {
47         DHLOGE("The parameter is nullptr");
48         return;
49     }
50     DAudioSinkManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_,
51         static_cast<int32_t>(message->type_), message->content_);
52 }
53 
OnEngineTransDataAvailable(const std::shared_ptr<AudioData> & audioData)54 void DSpeakerClient::OnEngineTransDataAvailable(const std::shared_ptr<AudioData> &audioData)
55 {
56     DHLOGE("On Engine Data available");
57     OnDecodeTransDataDone(audioData);
58 }
59 
InitReceiverEngine(IAVEngineProvider * providerPtr)60 int32_t DSpeakerClient::InitReceiverEngine(IAVEngineProvider *providerPtr)
61 {
62     DHLOGI("InitReceiverEngine enter.");
63     if (speakerTrans_ == nullptr) {
64         speakerTrans_ = std::make_shared<AVTransReceiverTransport>(devId_, shared_from_this());
65     }
66     int32_t ret = speakerTrans_->InitEngine(providerPtr);
67     if (ret != DH_SUCCESS) {
68         DHLOGE("Spk client initialize av receiver adapter failed.");
69         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
70     }
71     return DH_SUCCESS;
72 }
73 
CreateAudioRenderer(const AudioParam & param)74 int32_t DSpeakerClient::CreateAudioRenderer(const AudioParam &param)
75 {
76     DHLOGD("Set up spk client: {sampleRate: %d, bitFormat: %d, channelMask: %d," +
77         "frameSize: %d, contentType: %d, renderFlags: %d, streamUsage: %d}.",
78         param.comParam.sampleRate, param.comParam.bitFormat, param.comParam.channelMask, param.comParam.frameSize,
79         param.renderOpts.contentType, param.renderOpts.renderFlags, param.renderOpts.streamUsage);
80     audioParam_ = param;
81     AudioStandard::AudioRendererOptions rendererOptions = {
82         {
83             static_cast<AudioStandard::AudioSamplingRate>(audioParam_.comParam.sampleRate),
84             AudioStandard::AudioEncodingType::ENCODING_PCM,
85             static_cast<AudioStandard::AudioSampleFormat>(audioParam_.comParam.bitFormat),
86             static_cast<AudioStandard::AudioChannel>(audioParam_.comParam.channelMask),
87         },
88         {
89             static_cast<AudioStandard::ContentType>(audioParam_.renderOpts.contentType),
90             static_cast<AudioStandard::StreamUsage>(audioParam_.renderOpts.streamUsage),
91             audioParam_.renderOpts.renderFlags == MMAP_MODE ? AudioStandard::STREAM_FLAG_FAST : 0,
92         }
93     };
94     std::lock_guard<std::mutex> lck(devMtx_);
95     audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
96     if (audioRenderer_ == nullptr) {
97         DHLOGE("Audio renderer create failed.");
98         return ERR_DH_AUDIO_CLIENT_CREATE_RENDER_FAILED;
99     }
100     audioRenderer_ ->SetRendererCallback(shared_from_this());
101     if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
102         return DH_SUCCESS;
103     }
104     int32_t ret = audioRenderer_->SetRendererWriteCallback(shared_from_this());
105     if (ret != DH_SUCCESS) {
106         DHLOGE("Client save write callback failed.");
107         return ERR_DH_AUDIO_CLIENT_CREATE_RENDER_FAILED;
108     }
109     return DH_SUCCESS;
110 }
111 
OnWriteData(size_t length)112 void DSpeakerClient::OnWriteData(size_t length)
113 {
114     AudioStandard::BufferDesc bufDesc;
115     if (audioRenderer_ == nullptr) {
116         DHLOGE("AudioRenderer is nullptr.");
117         return;
118     }
119     int32_t ret = audioRenderer_->GetBufferDesc(bufDesc);
120     if (ret != DH_SUCCESS || bufDesc.buffer == nullptr || bufDesc.bufLength == 0) {
121         DHLOGE("Get buffer desc failed.");
122         return;
123     }
124     std::shared_ptr<AudioData> audioData = nullptr;
125     {
126         std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
127         dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT),
128             [this]() { return !dataQueue_.empty(); });
129         if (dataQueue_.empty()) {
130             return;
131         }
132         audioData = dataQueue_.front();
133         dataQueue_.pop();
134         DHLOGD("Pop spk data, dataQueue size: %d.", dataQueue_.size());
135     }
136     if (audioData->Capacity() != bufDesc.bufLength) {
137         DHLOGE("Audio data length is not equal to buflength. datalength: %d, bufLength: %d",
138             audioData->Capacity(), bufDesc.bufLength);
139     }
140     if (memcpy_s(bufDesc.buffer, bufDesc.bufLength, audioData->Data(), audioData->Capacity()) != EOK) {
141         DHLOGE("Copy audio data failed.");
142     }
143     audioRenderer_->Enqueue(bufDesc);
144 }
145 
SetUp(const AudioParam & param)146 int32_t DSpeakerClient::SetUp(const AudioParam &param)
147 {
148     int32_t ret = CreateAudioRenderer(param);
149     if (ret != DH_SUCCESS) {
150         DHLOGE("Set up failed, Create Audio renderer failed.");
151         return ret;
152     }
153     if (speakerTrans_ == nullptr) {
154         DHLOGE("Speaker trans should be init by dev.");
155         return ERR_DH_AUDIO_NULLPTR;
156     }
157     ret = speakerTrans_->SetUp(audioParam_, audioParam_, shared_from_this(), CAP_SPK);
158     if (ret != DH_SUCCESS) {
159         DHLOGE("Speaker trans setup failed.");
160         return ret;
161     }
162     ret = speakerTrans_->Start();
163     if (ret != DH_SUCCESS) {
164         DHLOGE("Speaker trans start failed.");
165         return ret;
166     }
167     auto pid = getpid();
168     ret = AudioStandard::AudioSystemManager::GetInstance()->RegisterVolumeKeyEventCallback(pid, shared_from_this());
169     if (ret != DH_SUCCESS) {
170         DHLOGE("Failed to register volume key event callback.");
171         return ret;
172     }
173     clientStatus_ = AudioStatus::STATUS_READY;
174     return DH_SUCCESS;
175 }
176 
Release()177 int32_t DSpeakerClient::Release()
178 {
179     DHLOGI("Release spk client.");
180     std::lock_guard<std::mutex> lck(devMtx_);
181     if (clientStatus_ != AudioStatus::STATUS_READY && clientStatus_ != AudioStatus::STATUS_STOP) {
182         DHLOGE("Speaker status %d is wrong.", (int32_t)clientStatus_);
183         return ERR_DH_AUDIO_SA_STATUS_ERR;
184     }
185     bool isSucess = true;
186     if (speakerTrans_ != nullptr) {
187         if (speakerTrans_->Stop() != DH_SUCCESS) {
188             DHLOGE("Speaker trans stop failed.");
189             isSucess = false;
190         }
191         if (speakerTrans_->Release() != DH_SUCCESS) {
192             DHLOGE("Speaker trans release failed.");
193             isSucess = false;
194         }
195         speakerTrans_ = nullptr;
196     }
197 
198     int32_t ret = AudioStandard::AudioSystemManager::GetInstance()->UnregisterVolumeKeyEventCallback(getpid());
199     if (ret != DH_SUCCESS) {
200         DHLOGE("Failed to unregister volume key event callback, error code %d.", ret);
201         isSucess = false;
202     }
203     if (audioRenderer_ != nullptr && !audioRenderer_->Release()) {
204         DHLOGE("Audio renderer release failed.");
205         isSucess = false;
206         audioRenderer_ = nullptr;
207     }
208     clientStatus_ = AudioStatus::STATUS_IDLE;
209     return isSucess ? DH_SUCCESS : ERR_DH_AUDIO_CLIENT_RENDER_RELEASE_FAILED;
210 }
211 
StartRender()212 int32_t DSpeakerClient::StartRender()
213 {
214     DHLOGI("Start spk client.");
215     std::lock_guard<std::mutex> lck(devMtx_);
216     if (audioRenderer_ == nullptr || clientStatus_ != AudioStatus::STATUS_READY) {
217         DHLOGE("Audio renderer init failed or spk status wrong, status: %d.", (int32_t)clientStatus_);
218         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR,
219             "daudio renderer init failed or spk status wrong.");
220         return ERR_DH_AUDIO_SA_STATUS_ERR;
221     }
222     if (!audioRenderer_->Start()) {
223         DHLOGE("Audio renderer start failed.");
224         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE,
225             "daudio renderer start failed.");
226         return ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE;
227     }
228     if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
229         isRenderReady_.store(true);
230         renderDataThread_ = std::thread(&DSpeakerClient::PlayThreadRunning, this);
231     }
232     clientStatus_ = AudioStatus::STATUS_START;
233     return DH_SUCCESS;
234 }
235 
StopRender()236 int32_t DSpeakerClient::StopRender()
237 {
238     DHLOGI("Stop spk client.");
239     std::lock_guard<std::mutex> lck(devMtx_);
240     if (clientStatus_ != AudioStatus::STATUS_START || !isRenderReady_.load()) {
241         DHLOGE("Renderer is not start or spk status wrong, status: %d.", (int32_t)clientStatus_);
242         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR,
243             "daudio renderer is not start or spk status wrong.");
244         return ERR_DH_AUDIO_SA_STATUS_ERR;
245     }
246     if (audioRenderer_ == nullptr) {
247         DHLOGE("Audio renderer is nullptr.");
248         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_OR_TRANS_IS_NULL,
249             "daudio renderer is nullptr.");
250         return ERR_DH_AUDIO_CLIENT_RENDER_OR_TRANS_IS_NULL;
251     }
252 
253     FlushJitterQueue();
254     if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
255         isRenderReady_.store(false);
256         if (renderDataThread_.joinable()) {
257             renderDataThread_.join();
258         }
259     }
260 
261     if (!audioRenderer_->Stop()) {
262         DHLOGE("Audio renderer stop failed");
263         DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED,
264             "daudio renderer stop failed.");
265         return ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED;
266     }
267     clientStatus_ = AudioStatus::STATUS_STOP;
268     return DH_SUCCESS;
269 }
270 
PlayThreadRunning()271 void DSpeakerClient::PlayThreadRunning()
272 {
273     DHLOGD("Start the renderer thread.");
274     if (pthread_setname_np(pthread_self(), RENDERTHREAD) != DH_SUCCESS) {
275         DHLOGE("Render data thread setname failed.");
276     }
277 
278     FillJitterQueue();
279     while (audioRenderer_ != nullptr && isRenderReady_.load()) {
280         std::shared_ptr<AudioData> audioData = nullptr;
281         {
282             std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
283             dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT),
284                 [this]() { return !dataQueue_.empty(); });
285             if (dataQueue_.empty()) {
286                 continue;
287             }
288             audioData = dataQueue_.front();
289             dataQueue_.pop();
290             DHLOGD("Pop spk data, dataqueue size: %d.", dataQueue_.size());
291         }
292 
293         int32_t writeOffSet = 0;
294         while (writeOffSet < static_cast<int32_t>(audioData->Capacity())) {
295             int32_t writeLen = audioRenderer_->Write(audioData->Data() + writeOffSet,
296                 static_cast<int32_t>(audioData->Capacity()) - writeOffSet);
297             DHLOGD("Write audio render, write len: %d, raw len: %d, offset: %d", writeLen, audioData->Capacity(),
298                 writeOffSet);
299             if (writeLen < 0) {
300                 break;
301             }
302             writeOffSet += writeLen;
303         }
304     }
305 }
306 
FillJitterQueue()307 void DSpeakerClient::FillJitterQueue()
308 {
309     while (isRenderReady_.load()) {
310         {
311             std::lock_guard<std::mutex> lock(dataQueueMtx_);
312             if (dataQueue_.size() >= DATA_QUEUE_SIZE) {
313                 break;
314             }
315         }
316         usleep(SLEEP_TIME);
317     }
318 }
319 
FlushJitterQueue()320 void DSpeakerClient::FlushJitterQueue()
321 {
322     while (true) {
323         {
324             std::lock_guard<std::mutex> lock(dataQueueMtx_);
325             if (dataQueue_.empty()) {
326                 break;
327             }
328         }
329         usleep(SLEEP_TIME);
330     }
331 }
332 
OnDecodeTransDataDone(const std::shared_ptr<AudioData> & audioData)333 int32_t DSpeakerClient::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData)
334 {
335     DHLOGI("Write stream buffer.");
336     if (audioData == nullptr) {
337         DHLOGE("The parameter is empty.");
338         return ERR_DH_AUDIO_CLIENT_PARAM_IS_NULL;
339     }
340     std::lock_guard<std::mutex> lock(dataQueueMtx_);
341     while (dataQueue_.size() > DATA_QUEUE_MAX_SIZE) {
342         DHLOGD("Data queue overflow.");
343         dataQueue_.pop();
344     }
345     dataQueue_.push(audioData);
346     dataQueueCond_.notify_all();
347     DHLOGI("Push new spk data, buf len: %d.", dataQueue_.size());
348     return DH_SUCCESS;
349 }
350 
OnStateChange(const AudioEventType type)351 int32_t DSpeakerClient::OnStateChange(const AudioEventType type)
352 {
353     DHLOGD("On state change. type: %d", type);
354     AudioEvent event;
355     switch (type) {
356         case AudioEventType::DATA_OPENED: {
357             event.type = AudioEventType::SPEAKER_OPENED;
358             event.content = GetVolumeLevel();
359             break;
360         }
361         case AudioEventType::DATA_CLOSED: {
362             event.type = AudioEventType::SPEAKER_CLOSED;
363             break;
364         }
365         default:
366             DHLOGE("Invalid parameter type: %d.", type);
367             return ERR_DH_AUDIO_CLIENT_STATE_IS_INVALID;
368     }
369 
370     std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
371     if (cbObj == nullptr) {
372         DHLOGE("Event callback is nullptr.");
373         return ERR_DH_AUDIO_CLIENT_EVENT_CALLBACK_IS_NULL;
374     }
375     cbObj->NotifyEvent(event);
376     return DH_SUCCESS;
377 }
378 
GetVolumeLevel()379 string DSpeakerClient::GetVolumeLevel()
380 {
381     DHLOGD("Get the volume level.");
382     std::stringstream ss;
383     AudioStandard::AudioStreamType streamType = AudioStandard::AudioStreamType::STREAM_DEFAULT;
384     auto volumeType = static_cast<AudioStandard::AudioVolumeType>(1);
385     int32_t volumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetVolume(volumeType);
386     int32_t maxVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMaxVolume(volumeType);
387     int32_t minVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMinVolume(volumeType);
388     bool isUpdateUi = false;
389     ss << "FIRST_VOLUME_CHANAGE;"
390        << "AUDIO_STREAM_TYPE=" << streamType << ";"
391        << "VOLUME_LEVEL=" << volumeLevel << ";"
392        << "IS_UPDATEUI=" << isUpdateUi << ";"
393        << "MAX_VOLUME_LEVEL=" << maxVolumeLevel << ";"
394        << "MIN_VOLUME_LEVEL=" << minVolumeLevel << ";";
395     std::string str = ss.str();
396     DHLOGD("Get the volume level result, event: %s.", str.c_str());
397     return str;
398 }
399 
OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent)400 void DSpeakerClient::OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent)
401 {
402     DHLOGD("Volume change event.");
403     std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
404     if (cbObj == nullptr) {
405         DHLOGE("Event callback is nullptr.");
406         return;
407     }
408     std::stringstream ss;
409     ss << "VOLUME_CHANAGE;"
410        << "AUDIO_STREAM_TYPE=" << volumeEvent.volumeType << ";"
411        << "VOLUME_LEVEL=" << volumeEvent.volume << ";"
412        << "IS_UPDATEUI=" << volumeEvent.updateUi << ";"
413        << "VOLUME_GROUP_ID=" << volumeEvent.volumeGroupId << ";";
414     std::string str = ss.str();
415     DHLOGD("Volume change notification result, event: %s.", str.c_str());
416 
417     AudioEvent audioEvent(VOLUME_CHANGE, str);
418     cbObj->NotifyEvent(audioEvent);
419 }
420 
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)421 void DSpeakerClient::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
422 {
423     DHLOGD("Audio focus interrupt event.");
424     std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
425     if (cbObj == nullptr) {
426         DHLOGE("Event callback is nullptr.");
427         return;
428     }
429     std::stringstream ss;
430     ss << "INTERRUPT_EVENT;"
431        << "EVENT_TYPE=" << interruptEvent.eventType << ";"
432        << "FORCE_TYPE=" << interruptEvent.forceType << ";"
433        << "HINT_TYPE=" << interruptEvent.hintType << ";";
434     std::string str = ss.str();
435     DHLOGD("Audio focus oninterrupt notification result, event: %s.", str.c_str());
436 
437     AudioEvent audioEvent(AUDIO_FOCUS_CHANGE, str);
438     cbObj->NotifyEvent(audioEvent);
439 }
440 
OnStateChange(const AudioStandard::RendererState state,const AudioStandard::StateChangeCmdType cmdType)441 void DSpeakerClient::OnStateChange(const AudioStandard::RendererState state,
442     const AudioStandard::StateChangeCmdType __attribute__((unused)) cmdType)
443 {
444     DHLOGD("On render state change. state: %d", state);
445     std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
446     if (cbObj == nullptr) {
447         DHLOGE("Event callback is nullptr.");
448         return;
449     }
450     std::stringstream ss;
451     ss << "RENDER_STATE_CHANGE_EVENT;"
452        << "STATE=" << state << ";";
453     std::string str = ss.str();
454     DHLOGD("Audio render state changes notification result, event: %s.", str.c_str());
455 
456     AudioEvent audioEvent(AUDIO_RENDER_STATE_CHANGE, str);
457     cbObj->NotifyEvent(audioEvent);
458 }
459 
SetAudioParameters(const AudioEvent & event)460 int32_t DSpeakerClient::SetAudioParameters(const AudioEvent &event)
461 {
462     DHLOGD("Set the volume, arg: %s.", event.content.c_str());
463 
464     int32_t audioVolumeType;
465     int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
466     if (ret != DH_SUCCESS) {
467         DHLOGE("Get audio volume type failed.");
468         return ret;
469     }
470     auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
471     DHLOGD("Audio volume type, volumeType = %d.", volumeType);
472     if (event.type != VOLUME_SET) {
473         DHLOGE("Invalid parameter.");
474         return ERR_DH_AUDIO_CLIENT_INVALID_VOLUME_PARAMETER;
475     }
476 
477     int32_t audioVolumeLevel;
478     ret = GetAudioParamInt(event.content, VOLUME_LEVEL, audioVolumeLevel);
479     if (ret != DH_SUCCESS) {
480         DHLOGE("Get audio volume level failed.");
481         return ret;
482     }
483     DHLOGD("volume level = %d.", audioVolumeLevel);
484     ret = AudioStandard::AudioSystemManager::GetInstance()->SetVolume(volumeType, audioVolumeLevel);
485     if (ret != DH_SUCCESS) {
486         DHLOGE("Voloume set failed.");
487         return ERR_DH_AUDIO_CLIENT_SET_VOLUME_FAILED;
488     }
489     return DH_SUCCESS;
490 }
491 
SetMute(const AudioEvent & event)492 int32_t DSpeakerClient::SetMute(const AudioEvent &event)
493 {
494     DHLOGD("Set mute, arg: %s.", event.content.c_str());
495     int32_t audioVolumeType;
496     int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
497     if (ret != DH_SUCCESS) {
498         DHLOGE("Get audio volume type failed.");
499         return ret;
500     }
501 
502     bool muteStatus = false;
503     ret = GetAudioParamBool(event.content, STREAM_MUTE_STATUS, muteStatus);
504     if (ret != DH_SUCCESS) {
505         DHLOGE("Get mute status failed.");
506         return ret;
507     }
508 
509     auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
510     DHLOGD("Audio volume type, volumeType = %d.", volumeType);
511     if (event.type != VOLUME_MUTE_SET) {
512         DHLOGE("Invalid parameter.");
513         return ERR_DH_AUDIO_CLIENT_INVALID_VOLUME_PARAMETER;
514     }
515     ret = AudioStandard::AudioSystemManager::GetInstance()->SetMute(volumeType, muteStatus);
516     if (ret != DH_SUCCESS) {
517         DHLOGE("Mute set failed.");
518         return ERR_DH_AUDIO_CLIENT_SET_MUTE_FAILED;
519     }
520     return DH_SUCCESS;
521 }
522 
Pause()523 void DSpeakerClient::Pause()
524 {
525     DHLOGI("Pause and flush");
526     FlushJitterQueue();
527     if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
528         isRenderReady_.store(false);
529         if (renderDataThread_.joinable()) {
530             renderDataThread_.join();
531         }
532     }
533 
534     if (speakerTrans_ == nullptr || speakerTrans_->Pause() != DH_SUCCESS) {
535         DHLOGE("Speaker trans Pause failed.");
536     }
537     if (audioRenderer_ != nullptr) {
538         audioRenderer_->Flush();
539     }
540     clientStatus_ = AudioStatus::STATUS_START;
541     isRenderReady_.store(true);
542 }
543 
ReStart()544 void DSpeakerClient::ReStart()
545 {
546     DHLOGI("ReStart");
547     if (speakerTrans_ == nullptr || speakerTrans_->Restart(audioParam_, audioParam_) != DH_SUCCESS) {
548         DHLOGE("Speaker trans Restart failed.");
549     }
550     if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
551         isRenderReady_.store(true);
552         renderDataThread_ = std::thread(&DSpeakerClient::PlayThreadRunning, this);
553     }
554     clientStatus_ = AudioStatus::STATUS_START;
555 }
556 
SendMessage(uint32_t type,std::string content,std::string dstDevId)557 int32_t DSpeakerClient::SendMessage(uint32_t type, std::string content, std::string dstDevId)
558 {
559     DHLOGI("Send message to remote.");
560     if (type != static_cast<uint32_t>(NOTIFY_OPEN_SPEAKER_RESULT) &&
561         type != static_cast<uint32_t>(NOTIFY_CLOSE_SPEAKER_RESULT) &&
562         type != static_cast<uint32_t>(VOLUME_CHANGE) &&
563         type != static_cast<uint32_t>(AUDIO_FOCUS_CHANGE) &&
564         type != static_cast<uint32_t>(AUDIO_RENDER_STATE_CHANGE)) {
565         DHLOGE("event type is not NOTIFY_OPEN_SPK or NOTIFY_CLOSE_SPK. type:%u", type);
566         return ERR_DH_AUDIO_NULLPTR;
567     }
568     if (speakerTrans_ == nullptr) {
569         DHLOGE("speaker trans is null.");
570         return ERR_DH_AUDIO_NULLPTR;
571     }
572     speakerTrans_->SendMessage(type, content, dstDevId);
573     return DH_SUCCESS;
574 }
575 
PlayStatusChange(const std::string & args)576 void DSpeakerClient::PlayStatusChange(const std::string &args)
577 {
578     DHLOGD("Play status change, args: %s.", args.c_str());
579     if (args == AUDIO_EVENT_RESTART) {
580         ReStart();
581     } else if (args == AUDIO_EVENT_PAUSE) {
582         Pause();
583     } else {
584         DHLOGE("Play status error.");
585     }
586 }
587 
SetAttrs(const std::string & devId,const std::shared_ptr<IAudioEventCallback> & callback)588 void DSpeakerClient::SetAttrs(const std::string &devId, const std::shared_ptr<IAudioEventCallback> &callback)
589 {
590     DHLOGE("Set attrs, not support yet.");
591 }
592 } // DistributedHardware
593 } // OHOS
594