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 "daudio_sink_dev.h"
17
18
19 #include <random>
20
21 #include "cJSON.h"
22
23 #include "daudio_constants.h"
24 #include "daudio_errorcode.h"
25 #include "daudio_log.h"
26 #include "daudio_sink_manager.h"
27 #include "daudio_util.h"
28
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "DAudioSinkDev"
31
32 namespace OHOS {
33 namespace DistributedHardware {
DAudioSinkDev(const std::string & devId,const sptr<IDAudioSinkIpcCallback> & sinkCallback)34 DAudioSinkDev::DAudioSinkDev(const std::string &devId, const sptr<IDAudioSinkIpcCallback> &sinkCallback)
35 : devId_(devId), ipcSinkCallback_(sinkCallback)
36 {
37 DHLOGD("Distributed audio sink device constructed, devId: %s.", GetAnonyString(devId).c_str());
38 }
39
~DAudioSinkDev()40 DAudioSinkDev::~DAudioSinkDev()
41 {
42 DHLOGD("Distributed audio sink device destructed, devId: %s.", GetAnonyString(devId_).c_str());
43 }
44
AwakeAudioDev()45 int32_t DAudioSinkDev::AwakeAudioDev()
46 {
47 auto runner = AppExecFwk::EventRunner::Create(true);
48 CHECK_NULL_RETURN(runner, ERR_DH_AUDIO_NULLPTR);
49 handler_ = std::make_shared<DAudioSinkDev::SinkEventHandler>(runner, shared_from_this());
50 return DH_SUCCESS;
51 }
52
SleepAudioDev()53 void DAudioSinkDev::SleepAudioDev()
54 {
55 DHLOGD("Sleep audio dev.");
56 CHECK_NULL_VOID(handler_);
57 while (!handler_->IsIdle()) {
58 DHLOGD("handler is running, wait for idle.");
59 usleep(WAIT_HANDLER_IDLE_TIME_US);
60 }
61 DHLOGI("Sleep audio dev over.");
62 }
63
InitAVTransEngines(const ChannelState channelState,IAVEngineProvider * providerPtr)64 int32_t DAudioSinkDev::InitAVTransEngines(const ChannelState channelState, IAVEngineProvider *providerPtr)
65 {
66 DHLOGI("Init InitAVTransEngines");
67 CHECK_NULL_RETURN(providerPtr, ERR_DH_AUDIO_FAILED);
68
69 if (channelState == ChannelState::UNKNOWN) {
70 DHLOGE("The channel type is invalid.");
71 return ERR_DH_AUDIO_FAILED;
72 }
73 if (channelState == ChannelState::MIC_CONTROL_OPENED) {
74 // only supports normal audio channel mode
75 std::lock_guard<std::mutex> devLck(micClientMutex_);
76 micClientMap_[DEFAULT_CAPTURE_ID] = std::make_shared<DMicClient>(devId_, DEFAULT_CAPTURE_ID,
77 shared_from_this());
78 micClientMap_[DEFAULT_CAPTURE_ID]->InitSenderEngine(providerPtr);
79 }
80
81 if (channelState == ChannelState::SPK_CONTROL_OPENED) {
82 spkClientMap_[DEFAULT_RENDER_ID] =
83 std::make_shared<DSpeakerClient>(devId_, DEFAULT_RENDER_ID, shared_from_this());
84 spkClientMap_[DEFAULT_RENDER_ID]->InitReceiverEngine(providerPtr);
85 spkClientMap_[LOW_LATENCY_RENDER_ID] =
86 std::make_shared<DSpeakerClient>(devId_, LOW_LATENCY_RENDER_ID, shared_from_this());
87 spkClientMap_[LOW_LATENCY_RENDER_ID]->InitReceiverEngine(providerPtr);
88 }
89 return DH_SUCCESS;
90 }
91
NotifyEvent(const AudioEvent & audioEvent)92 void DAudioSinkDev::NotifyEvent(const AudioEvent &audioEvent)
93 {
94 DHLOGD("Notify event, eventType: %d.", (int32_t)audioEvent.type);
95 if ((int32_t)audioEvent.type == DISABLE_DEVICE) {
96 TaskDisableDevice(audioEvent.content);
97 return;
98 }
99 auto eventParam = std::make_shared<AudioEvent>(audioEvent);
100 auto msgEvent = AppExecFwk::InnerEvent::Get(static_cast<uint32_t>(audioEvent.type), eventParam, 0);
101 CHECK_NULL_VOID(handler_);
102 if (handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
103 DHLOGD("Send event success.");
104 }
105 }
106
TaskDisableDevice(const std::string & args)107 int32_t DAudioSinkDev::TaskDisableDevice(const std::string &args)
108 {
109 if (args.find(OWNER_NAME_D_SPEAKER) != args.npos) {
110 isSpkInUse_.store(false);
111 }
112 if (args.find(OWNER_NAME_D_MIC) != args.npos) {
113 isMicInUse_.store(false);
114 }
115 JudgeDeviceStatus();
116 return DH_SUCCESS;
117 }
118
TaskOpenDSpeaker(const std::string & args)119 int32_t DAudioSinkDev::TaskOpenDSpeaker(const std::string &args)
120 {
121 DHLOGI("Open speaker device, args = %s.", args.c_str());
122 if (args.length() > DAUDIO_MAX_JSON_LEN || args.empty()) {
123 return ERR_DH_AUDIO_SA_PARAM_INVALID;
124 }
125 json jParam = json::parse(args, nullptr, false);
126 if (!JsonParamCheck(jParam, { KEY_DH_ID, KEY_AUDIO_PARAM })) {
127 return ERR_DH_AUDIO_FAILED;
128 }
129 int32_t dhId = ConvertString2Int(std::string(jParam[KEY_DH_ID]));
130 if (dhId == -1) {
131 DHLOGE("Parse dhId error.");
132 return ERR_DH_AUDIO_NULLPTR;
133 }
134 std::shared_ptr<ISpkClient> speakerClient = nullptr;
135 {
136 std::lock_guard<std::mutex> devLck(spkClientMutex_);
137 speakerClient = spkClientMap_[dhId];
138 }
139 AudioParam audioParam;
140 int32_t ret = from_json(jParam[KEY_AUDIO_PARAM], audioParam);
141 if (ret != DH_SUCCESS) {
142 DHLOGE("Get audio param from json failed, error code %d.", ret);
143 return ret;
144 }
145
146 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
147 ret = speakerClient->SetUp(audioParam);
148 if (ret != DH_SUCCESS) {
149 DHLOGE("Setup speaker failed, ret: %d.", ret);
150 return ret;
151 }
152 isSpkInUse_.store(true);
153 return ret;
154 }
155
TaskCloseDSpeaker(const std::string & args)156 int32_t DAudioSinkDev::TaskCloseDSpeaker(const std::string &args)
157 {
158 DHLOGI("Close speaker device.");
159 int32_t dhId = ParseDhidFromEvent(args);
160 if (dhId < 0) {
161 DHLOGE("Failed to parse dhardware id.");
162 return ERR_DH_AUDIO_FAILED;
163 }
164 std::lock_guard<std::mutex> devLck(spkClientMutex_);
165 auto speakerClient = spkClientMap_[dhId];
166 CHECK_NULL_RETURN(speakerClient, DH_SUCCESS);
167
168 int32_t ret = speakerClient->StopRender();
169 if (ret != DH_SUCCESS) {
170 DHLOGE("Stop speaker client failed, ret: %d.", ret);
171 }
172 ret = speakerClient->Release();
173 if (ret != DH_SUCCESS) {
174 DHLOGE("Release speaker client failed, ret: %d.", ret);
175 }
176 spkClientMap_.erase(dhId);
177 DHLOGI("Close speaker device task excute success.");
178 return DH_SUCCESS;
179 }
180
ParseDhidFromEvent(std::string args)181 int32_t DAudioSinkDev::ParseDhidFromEvent(std::string args)
182 {
183 DHLOGI("ParseDhidFrom args : %s", args.c_str());
184 cJSON *jParam = cJSON_Parse(args.c_str());
185 CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_FAILED);
186
187 if (!CJsonParamCheck(jParam, { KEY_DH_ID })) {
188 DHLOGE("Not found the keys of dhId.");
189 cJSON_Delete(jParam);
190 return -1;
191 }
192 cJSON *dhIdItem = cJSON_GetObjectItem(jParam, KEY_DH_ID);
193 if (dhIdItem == NULL || !cJSON_IsString(dhIdItem)) {
194 DHLOGE("Not found the keys of dhId.");
195 cJSON_Delete(jParam);
196 return ERR_DH_AUDIO_FAILED;
197 }
198 int32_t dhId = ConvertString2Int(std::string(dhIdItem->valuestring));
199 cJSON_Delete(jParam);
200 DHLOGI("Parsed dhId is: %d.", dhId);
201 return dhId;
202 }
203
TaskStartRender(const std::string & args)204 int32_t DAudioSinkDev::TaskStartRender(const std::string &args)
205 {
206 int32_t dhId = ParseDhidFromEvent(args);
207 if (dhId < 0) {
208 DHLOGE("Failed to parse dhardware id.");
209 return ERR_DH_AUDIO_FAILED;
210 }
211 std::shared_ptr<ISpkClient> speakerClient = nullptr;
212 {
213 std::lock_guard<std::mutex> devLck(spkClientMutex_);
214 speakerClient = spkClientMap_[dhId];
215 }
216 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
217
218 int32_t ret = speakerClient->StartRender();
219 if (ret != DH_SUCCESS) {
220 DHLOGE("Start render failed. ret: %d.", ret);
221 return ret;
222 }
223 DHLOGI("Start render success.");
224 return DH_SUCCESS;
225 }
226
TaskOpenDMic(const std::string & args)227 int32_t DAudioSinkDev::TaskOpenDMic(const std::string &args)
228 {
229 DHLOGI("Open mic device.");
230 if (args.length() > DAUDIO_MAX_JSON_LEN || args.empty()) {
231 return ERR_DH_AUDIO_SA_PARAM_INVALID;
232 }
233 json jParam = json::parse(args, nullptr, false);
234 if (!JsonParamCheck(jParam, { KEY_DH_ID, KEY_AUDIO_PARAM })) {
235 return ERR_DH_AUDIO_FAILED;
236 }
237 AudioParam audioParam;
238 int32_t ret = from_json(jParam[KEY_AUDIO_PARAM], audioParam);
239 if (ret != DH_SUCCESS) {
240 DHLOGE("Get audio param from json failed, error code %d.", ret);
241 return ret;
242 }
243 micDhId_ = std::string(jParam[KEY_DH_ID]);
244 int32_t dhId = ConvertString2Int(std::string(jParam[KEY_DH_ID]));
245 if (dhId == -1) {
246 DHLOGE("Parse dhId error.");
247 return ERR_DH_AUDIO_NULLPTR;
248 }
249 std::shared_ptr<DMicClient> micClient = nullptr;
250 {
251 std::lock_guard<std::mutex> devLck(micClientMutex_);
252 micClient = micClientMap_[dhId];
253 }
254 CHECK_NULL_RETURN(micClient, ERR_DH_AUDIO_NULLPTR);
255
256 ret = micClient->SetUp(audioParam);
257 if (ret != DH_SUCCESS) {
258 DHLOGE("Set up mic failed, ret: %d.", ret);
259 return ERR_DH_AUDIO_FAILED;
260 }
261 ret = micClient->StartCapture();
262 if (ret != DH_SUCCESS) {
263 DHLOGE("Start capture failed, ret: %d.", ret);
264 return ERR_DH_AUDIO_FAILED;
265 }
266 PullUpPage();
267 isMicInUse_.store(true);
268 return ret;
269 }
270
TaskCloseDMic(const std::string & args)271 int32_t DAudioSinkDev::TaskCloseDMic(const std::string &args)
272 {
273 DHLOGI("Close mic device.");
274 int32_t dhId = ParseDhidFromEvent(args);
275 if (dhId < 0) {
276 DHLOGE("Failed to parse dhardware id.");
277 return ERR_DH_AUDIO_FAILED;
278 }
279 std::lock_guard<std::mutex> devLck(micClientMutex_);
280 std::shared_ptr<DMicClient> micClient = micClientMap_[dhId];
281 CHECK_NULL_RETURN(micClient, DH_SUCCESS);
282
283 int32_t ret = micClient->StopCapture();
284 if (ret != DH_SUCCESS) {
285 DHLOGE("Stop mic client failed, ret: %d.", ret);
286 }
287 ret = micClient->Release();
288 if (ret != DH_SUCCESS) {
289 DHLOGE("Release mic client failed, ret: %d.", ret);
290 }
291 micClientMap_.erase(dhId);
292 if (isPageStatus_.load()) {
293 bool isSensitive = false;
294 bool isSameAccount = false;
295 ipcSinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_CLOSE_PAGE, SUBTYPE, devId_,
296 isSensitive, isSameAccount);
297 }
298 isPageStatus_.store(false);
299 DHLOGI("Close mic device task excute success.");
300 return DH_SUCCESS;
301 }
302
TaskSetParameter(const std::string & args)303 int32_t DAudioSinkDev::TaskSetParameter(const std::string &args)
304 {
305 DHLOGD("Set audio param.");
306 AudioEvent event(AudioEventType::EVENT_UNKNOWN, args);
307 int32_t dhId = ParseDhidFromEvent(args);
308 if (dhId < 0) {
309 DHLOGE("Failed to parse dhardware id.");
310 return ERR_DH_AUDIO_FAILED;
311 }
312 std::shared_ptr<ISpkClient> speakerClient = nullptr;
313 {
314 std::lock_guard<std::mutex> devLck(spkClientMutex_);
315 speakerClient = spkClientMap_[dhId];
316 }
317 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
318 return speakerClient->SetAudioParameters(event);
319 }
320
TaskSetVolume(const std::string & args)321 int32_t DAudioSinkDev::TaskSetVolume(const std::string &args)
322 {
323 DHLOGD("Set audio volume.");
324 int32_t dhId = 0;
325 if (GetAudioParamInt(args, "dhId", dhId) != DH_SUCCESS) {
326 DHLOGE("Get key of dhId failed.");
327 return ERR_DH_AUDIO_FAILED;
328 }
329 std::shared_ptr<ISpkClient> speakerClient = nullptr;
330 {
331 std::lock_guard<std::mutex> devLck(spkClientMutex_);
332 speakerClient = spkClientMap_[dhId];
333 }
334 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
335
336 AudioEvent event(AudioEventType::VOLUME_SET, args);
337 int32_t ret = speakerClient->SetAudioParameters(event);
338 if (ret != DH_SUCCESS) {
339 DHLOGE("Volume set failed, ret: %d.", ret);
340 return ret;
341 }
342 DHLOGD("Set audio volume success.");
343 return DH_SUCCESS;
344 }
345
TaskSetMute(const std::string & args)346 int32_t DAudioSinkDev::TaskSetMute(const std::string &args)
347 {
348 DHLOGD("Set audio mute.");
349 int dhId = 0;
350 if (GetAudioParamInt(args, "dhId", dhId) != DH_SUCCESS) {
351 DHLOGE("Get key of dhId failed.");
352 return ERR_DH_AUDIO_FAILED;
353 }
354 std::shared_ptr<ISpkClient> speakerClient = nullptr;
355 {
356 std::lock_guard<std::mutex> devLck(spkClientMutex_);
357 speakerClient = spkClientMap_[dhId];
358 }
359 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
360
361 AudioEvent event(AudioEventType::VOLUME_MUTE_SET, args);
362 int32_t ret = speakerClient->SetMute(event);
363 if (ret != DH_SUCCESS) {
364 DHLOGE("Set mute failed, ret: %d.", ret);
365 return ret;
366 }
367 DHLOGD("Set mute success.");
368 return DH_SUCCESS;
369 }
370
TaskVolumeChange(const std::string & args)371 int32_t DAudioSinkDev::TaskVolumeChange(const std::string &args)
372 {
373 DHLOGD("Audio volume changed.");
374 AudioEvent event(AudioEventType::VOLUME_CHANGE, args);
375 return SendAudioEventToRemote(event);
376 }
377
TaskFocusChange(const std::string & args)378 int32_t DAudioSinkDev::TaskFocusChange(const std::string &args)
379 {
380 DHLOGD("Audio focus changed.");
381 AudioEvent event(AudioEventType::AUDIO_FOCUS_CHANGE, args);
382 return SendAudioEventToRemote(event);
383 }
384
TaskRenderStateChange(const std::string & args)385 int32_t DAudioSinkDev::TaskRenderStateChange(const std::string &args)
386 {
387 DHLOGD("Audio render state changed.");
388 AudioEvent event(AudioEventType::AUDIO_RENDER_STATE_CHANGE, args);
389 return SendAudioEventToRemote(event);
390 }
391
TaskPlayStatusChange(const std::string & args)392 int32_t DAudioSinkDev::TaskPlayStatusChange(const std::string &args)
393 {
394 DHLOGD("Play status change, content: %s.", args.c_str());
395 int32_t dhId = ParseDhidFromEvent(args);
396 if (dhId < 0) {
397 DHLOGE("Failed to parse dhardware id.");
398 return ERR_DH_AUDIO_FAILED;
399 }
400 std::shared_ptr<ISpkClient> speakerClient = nullptr;
401 {
402 std::lock_guard<std::mutex> devLck(spkClientMutex_);
403 speakerClient = spkClientMap_[dhId];
404 }
405 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
406 speakerClient->PlayStatusChange(args);
407 DHLOGD("Play status change success.");
408 return DH_SUCCESS;
409 }
410
SendAudioEventToRemote(const AudioEvent & event)411 int32_t DAudioSinkDev::SendAudioEventToRemote(const AudioEvent &event)
412 {
413 // because: type: VOLUME_CHANGE / AUDIO_FOCUS_CHANGE / AUDIO_RENDER_STATE_CHANGE
414 // so speakerClient
415 int32_t dhId = ParseDhidFromEvent(event.content);
416 if (dhId < 0) {
417 DHLOGE("Failed to parse dhardware id.");
418 return ERR_DH_AUDIO_FAILED;
419 }
420 std::shared_ptr<ISpkClient> speakerClient = nullptr;
421 {
422 std::lock_guard<std::mutex> devLck(spkClientMutex_);
423 speakerClient = spkClientMap_[dhId];
424 }
425 CHECK_NULL_RETURN(speakerClient, ERR_DH_AUDIO_NULLPTR);
426
427 int32_t ret = speakerClient->SendMessage(static_cast<uint32_t>(event.type),
428 event.content, devId_);
429 if (ret != DH_SUCCESS) {
430 DHLOGE("Task send message to remote failed.");
431 return ERR_DH_AUDIO_NULLPTR;
432 }
433 return DH_SUCCESS;
434 }
435
JudgeDeviceStatus()436 void DAudioSinkDev::JudgeDeviceStatus()
437 {
438 DHLOGI("Checking device's status.");
439 if (isSpkInUse_.load() || isMicInUse_.load()) {
440 DHLOGI("Device contain periperials in using, speaker status: %d, mic status: %d.",
441 isSpkInUse_.load(), isMicInUse_.load());
442 return;
443 }
444 DAudioSinkManager::GetInstance().OnSinkDevReleased(devId_);
445 }
446
ConvertString2Int(std::string val)447 int32_t DAudioSinkDev::ConvertString2Int(std::string val)
448 {
449 if (!CheckIsNum(val)) {
450 DHLOGE("String is not number. str:%s.", val.c_str());
451 return -1;
452 }
453 return std::stoi(val);
454 }
455
PullUpPage()456 void DAudioSinkDev::PullUpPage()
457 {
458 bool isSensitive = false;
459 bool isSameAccount = false;
460 ipcSinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_PULL_UP_PAGE, SUBTYPE, devId_,
461 isSensitive, isSameAccount);
462 isPageStatus_.store(true);
463 }
464
NotifySourceDev(const AudioEventType type,const std::string dhId,const int32_t result)465 void DAudioSinkDev::NotifySourceDev(const AudioEventType type, const std::string dhId, const int32_t result)
466 {
467 std::random_device rd;
468 const uint32_t randomTaskCode = rd();
469 json jEvent;
470 jEvent[KEY_DH_ID] = dhId;
471 jEvent[KEY_RESULT] = result;
472 jEvent[KEY_EVENT_TYPE] = type;
473 jEvent[KEY_RANDOM_TASK_CODE] = std::to_string(randomTaskCode);
474
475 DHLOGD("Notify source dev, new engine, random task code:%s", std::to_string(randomTaskCode).c_str());
476 if (type == NOTIFY_OPEN_CTRL_RESULT || type == NOTIFY_CLOSE_CTRL_RESULT) {
477 DHLOGE("In new engine mode, ctrl is not allowed.");
478 return;
479 }
480 int32_t dhIdInt = ConvertString2Int(dhId);
481 if (dhIdInt == -1) {
482 DHLOGE("Parse dhId error.");
483 return;
484 }
485 std::shared_ptr<ISpkClient> speakerClient = nullptr;
486 {
487 std::lock_guard<std::mutex> devLck(spkClientMutex_);
488 speakerClient = spkClientMap_[dhIdInt];
489 }
490 if (speakerClient != nullptr) {
491 speakerClient->SendMessage(static_cast<uint32_t>(type), jEvent.dump(), devId_);
492 }
493 std::shared_ptr<DMicClient> micClient = nullptr;
494 {
495 std::lock_guard<std::mutex> devLck(micClientMutex_);
496 micClient = micClientMap_[dhIdInt];
497 }
498 if (micClient != nullptr) {
499 micClient->SendMessage(static_cast<uint32_t>(type), jEvent.dump(), devId_);
500 }
501 }
502
from_json(const json & j,AudioParam & audioParam)503 int32_t DAudioSinkDev::from_json(const json &j, AudioParam &audioParam)
504 {
505 if (!JsonParamCheck(j, { KEY_SAMPLING_RATE, KEY_CHANNELS, KEY_FORMAT,
506 KEY_SOURCE_TYPE, KEY_CONTENT_TYPE, KEY_STREAM_USAGE })) {
507 return ERR_DH_AUDIO_FAILED;
508 }
509 j.at(KEY_SAMPLING_RATE).get_to(audioParam.comParam.sampleRate);
510 j.at(KEY_CHANNELS).get_to(audioParam.comParam.channelMask);
511 j.at(KEY_FORMAT).get_to(audioParam.comParam.bitFormat);
512 j.at(KEY_FRAMESIZE).get_to(audioParam.comParam.frameSize);
513 j.at(KEY_SOURCE_TYPE).get_to(audioParam.captureOpts.sourceType);
514 j.at(KEY_CONTENT_TYPE).get_to(audioParam.renderOpts.contentType);
515 j.at(KEY_STREAM_USAGE).get_to(audioParam.renderOpts.streamUsage);
516 j.at(KEY_RENDER_FLAGS).get_to(audioParam.renderOpts.renderFlags);
517 j.at(KEY_CAPTURE_FLAGS).get_to(audioParam.captureOpts.capturerFlags);
518 return DH_SUCCESS;
519 }
520
HandleEngineMessage(uint32_t type,std::string content,std::string devId)521 int32_t DAudioSinkDev::HandleEngineMessage(uint32_t type, std::string content, std::string devId)
522 {
523 DHLOGI("HandleEngineMessage enter.");
524 return DAudioSinkManager::GetInstance().HandleDAudioNotify(devId, devId, static_cast<int32_t>(type), content);
525 }
526
SinkEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,const std::shared_ptr<DAudioSinkDev> & dev)527 DAudioSinkDev::SinkEventHandler::SinkEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
528 const std::shared_ptr<DAudioSinkDev> &dev) : AppExecFwk::EventHandler(runner), sinkDev_(dev)
529 {
530 DHLOGD("Event handler is constructing.");
531 mapEventFuncs_[static_cast<uint32_t>(CTRL_OPENED)] = &DAudioSinkDev::SinkEventHandler::NotifyCtrlOpened;
532 mapEventFuncs_[static_cast<uint32_t>(CTRL_CLOSED)] = &DAudioSinkDev::SinkEventHandler::NotifyCtrlClosed;
533 mapEventFuncs_[static_cast<uint32_t>(OPEN_SPEAKER)] = &DAudioSinkDev::SinkEventHandler::NotifyOpenSpeaker;
534 mapEventFuncs_[static_cast<uint32_t>(CLOSE_SPEAKER)] = &DAudioSinkDev::SinkEventHandler::NotifyCloseSpeaker;
535 mapEventFuncs_[static_cast<uint32_t>(SPEAKER_OPENED)] = &DAudioSinkDev::SinkEventHandler::NotifySpeakerOpened;
536 mapEventFuncs_[static_cast<uint32_t>(SPEAKER_CLOSED)] = &DAudioSinkDev::SinkEventHandler::NotifySpeakerClosed;
537 mapEventFuncs_[static_cast<uint32_t>(OPEN_MIC)] = &DAudioSinkDev::SinkEventHandler::NotifyOpenMic;
538 mapEventFuncs_[static_cast<uint32_t>(CLOSE_MIC)] = &DAudioSinkDev::SinkEventHandler::NotifyCloseMic;
539 mapEventFuncs_[static_cast<uint32_t>(MIC_OPENED)] = &DAudioSinkDev::SinkEventHandler::NotifyMicOpened;
540 mapEventFuncs_[static_cast<uint32_t>(MIC_CLOSED)] = &DAudioSinkDev::SinkEventHandler::NotifyMicClosed;
541 mapEventFuncs_[static_cast<uint32_t>(VOLUME_SET)] = &DAudioSinkDev::SinkEventHandler::NotifySetVolume;
542 mapEventFuncs_[static_cast<uint32_t>(VOLUME_CHANGE)] = &DAudioSinkDev::SinkEventHandler::NotifyVolumeChange;
543 mapEventFuncs_[static_cast<uint32_t>(SET_PARAM)] = &DAudioSinkDev::SinkEventHandler::NotifySetParam;
544 mapEventFuncs_[static_cast<uint32_t>(VOLUME_MUTE_SET)] = &DAudioSinkDev::SinkEventHandler::NotifySetMute;
545 mapEventFuncs_[static_cast<uint32_t>(AUDIO_FOCUS_CHANGE)] = &DAudioSinkDev::SinkEventHandler::NotifyFocusChange;
546 mapEventFuncs_[static_cast<uint32_t>(AUDIO_RENDER_STATE_CHANGE)] =
547 &DAudioSinkDev::SinkEventHandler::NotifyRenderStateChange;
548 mapEventFuncs_[static_cast<uint32_t>(CHANGE_PLAY_STATUS)] =
549 &DAudioSinkDev::SinkEventHandler::NotifyPlayStatusChange;
550 }
551
~SinkEventHandler()552 DAudioSinkDev::SinkEventHandler::~SinkEventHandler() {}
553
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)554 void DAudioSinkDev::SinkEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
555 {
556 auto iter = mapEventFuncs_.find(event->GetInnerEventId());
557 if (iter == mapEventFuncs_.end()) {
558 DHLOGE("Event Id is invaild. %d", event->GetInnerEventId());
559 return;
560 }
561 SinkEventFunc &func = iter->second;
562 (this->*func)(event);
563 }
564
NotifyCtrlOpened(const AppExecFwk::InnerEvent::Pointer & event)565 void DAudioSinkDev::SinkEventHandler::NotifyCtrlOpened(const AppExecFwk::InnerEvent::Pointer &event)
566 {
567 DHLOGI("Ctrl channel is opened.");
568 (void)event;
569 }
570
NotifyCtrlClosed(const AppExecFwk::InnerEvent::Pointer & event)571 void DAudioSinkDev::SinkEventHandler::NotifyCtrlClosed(const AppExecFwk::InnerEvent::Pointer &event)
572 {
573 DHLOGI("Notify ctrl closed.");
574 std::string eventParam;
575 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
576 DHLOGE("Failed to get event parameters.");
577 return;
578 }
579 auto sinkDevObj = sinkDev_.lock();
580 CHECK_NULL_VOID(sinkDevObj);
581 if (sinkDevObj->TaskCloseDSpeaker(eventParam) != DH_SUCCESS) {
582 DHLOGE("Close speaker failed.");
583 return;
584 }
585 if (sinkDevObj->TaskCloseDMic(eventParam) != DH_SUCCESS) {
586 DHLOGE("Close mic failed.");
587 return;
588 }
589 sinkDevObj->JudgeDeviceStatus();
590 }
591
NotifyOpenSpeaker(const AppExecFwk::InnerEvent::Pointer & event)592 void DAudioSinkDev::SinkEventHandler::NotifyOpenSpeaker(const AppExecFwk::InnerEvent::Pointer &event)
593 {
594 std::string eventParam;
595 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
596 DHLOGE("Failed to get event parameters.");
597 return;
598 }
599 auto sinkDevObj = sinkDev_.lock();
600 CHECK_NULL_VOID(sinkDevObj);
601
602 json jParam = json::parse(eventParam, nullptr, false);
603 if (!JsonParamCheck(jParam, { KEY_DH_ID, KEY_AUDIO_PARAM })) {
604 DHLOGE("Json param check failed.");
605 return;
606 }
607 int32_t ret = sinkDevObj->TaskOpenDSpeaker(eventParam);
608 sinkDevObj->NotifySourceDev(NOTIFY_OPEN_SPEAKER_RESULT, jParam[KEY_DH_ID], ret);
609 DHLOGI("Open speaker device task end, notify source ret %d.", ret);
610 if (ret != DH_SUCCESS) {
611 DHLOGE("Open speaker failed.");
612 return;
613 }
614 }
615
NotifyCloseSpeaker(const AppExecFwk::InnerEvent::Pointer & event)616 void DAudioSinkDev::SinkEventHandler::NotifyCloseSpeaker(const AppExecFwk::InnerEvent::Pointer &event)
617 {
618 std::string eventParam;
619 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
620 DHLOGE("Failed to get event parameters.");
621 return;
622 }
623 auto sinkDevObj = sinkDev_.lock();
624 CHECK_NULL_VOID(sinkDevObj);
625 if (sinkDevObj->TaskCloseDSpeaker(eventParam) != DH_SUCCESS) {
626 DHLOGE("Open speaker failed.");
627 return;
628 }
629 }
630
NotifySpeakerOpened(const AppExecFwk::InnerEvent::Pointer & event)631 void DAudioSinkDev::SinkEventHandler::NotifySpeakerOpened(const AppExecFwk::InnerEvent::Pointer &event)
632 {
633 DHLOGD("Starting render.");
634 std::string eventParam;
635 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
636 DHLOGE("Failed to get event parameters.");
637 return;
638 }
639 auto sinkDevObj = sinkDev_.lock();
640 CHECK_NULL_VOID(sinkDevObj);
641
642 if (sinkDevObj->TaskStartRender(eventParam) != DH_SUCCESS) {
643 DHLOGE("Speaker client start failed.");
644 return;
645 }
646 if (sinkDevObj->TaskVolumeChange(eventParam) != DH_SUCCESS) {
647 DHLOGE("Notify pimary volume to source device failed.");
648 return;
649 }
650 }
651
NotifySpeakerClosed(const AppExecFwk::InnerEvent::Pointer & event)652 void DAudioSinkDev::SinkEventHandler::NotifySpeakerClosed(const AppExecFwk::InnerEvent::Pointer &event)
653 {
654 std::string eventParam;
655 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
656 DHLOGE("Failed to get event parameters.");
657 return;
658 }
659 auto sinkDevObj = sinkDev_.lock();
660 CHECK_NULL_VOID(sinkDevObj);
661
662 if (sinkDevObj->TaskCloseDSpeaker(eventParam) != DH_SUCCESS) {
663 DHLOGE("Close speaker failed.");
664 return;
665 }
666 }
667
NotifyOpenMic(const AppExecFwk::InnerEvent::Pointer & event)668 void DAudioSinkDev::SinkEventHandler::NotifyOpenMic(const AppExecFwk::InnerEvent::Pointer &event)
669 {
670 std::string eventParam;
671 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
672 DHLOGE("Failed to get event parameters.");
673 return;
674 }
675 auto sinkDevObj = sinkDev_.lock();
676 CHECK_NULL_VOID(sinkDevObj);
677
678 json jParam = json::parse(eventParam, nullptr, false);
679 if (!JsonParamCheck(jParam, { KEY_DH_ID, KEY_AUDIO_PARAM })) {
680 DHLOGE("Json param check failed.");
681 return;
682 }
683 int32_t ret = sinkDevObj->TaskOpenDMic(eventParam);
684 sinkDevObj->NotifySourceDev(NOTIFY_OPEN_MIC_RESULT, jParam[KEY_DH_ID], ret);
685 DHLOGI("Open mic device task end, notify source ret %d.", ret);
686 if (ret != DH_SUCCESS) {
687 DHLOGE("Open mic failed.");
688 return;
689 }
690 }
691
NotifyCloseMic(const AppExecFwk::InnerEvent::Pointer & event)692 void DAudioSinkDev::SinkEventHandler::NotifyCloseMic(const AppExecFwk::InnerEvent::Pointer &event)
693 {
694 std::string eventParam;
695 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
696 DHLOGE("Failed to get event parameters.");
697 return;
698 }
699 auto sinkDevObj = sinkDev_.lock();
700 CHECK_NULL_VOID(sinkDevObj);
701
702 if (sinkDevObj->TaskCloseDMic(eventParam) != DH_SUCCESS) {
703 DHLOGE("Close mic failed.");
704 return;
705 }
706 }
707
NotifyMicOpened(const AppExecFwk::InnerEvent::Pointer & event)708 void DAudioSinkDev::SinkEventHandler::NotifyMicOpened(const AppExecFwk::InnerEvent::Pointer &event)
709 {
710 DHLOGI("Notify mic is opened.");
711 (void)event;
712 }
713
NotifyMicClosed(const AppExecFwk::InnerEvent::Pointer & event)714 void DAudioSinkDev::SinkEventHandler::NotifyMicClosed(const AppExecFwk::InnerEvent::Pointer &event)
715 {
716 std::string eventParam;
717 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
718 DHLOGE("Failed to get event parameters.");
719 return;
720 }
721 auto sinkDevObj = sinkDev_.lock();
722 CHECK_NULL_VOID(sinkDevObj);
723
724 if (sinkDevObj->TaskCloseDMic(eventParam) != DH_SUCCESS) {
725 DHLOGE("Close mic failed.");
726 return;
727 }
728 }
729
NotifySetVolume(const AppExecFwk::InnerEvent::Pointer & event)730 void DAudioSinkDev::SinkEventHandler::NotifySetVolume(const AppExecFwk::InnerEvent::Pointer &event)
731 {
732 std::string eventParam;
733 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
734 DHLOGE("Failed to get event parameters.");
735 return;
736 }
737 auto sinkDevObj = sinkDev_.lock();
738 CHECK_NULL_VOID(sinkDevObj);
739
740 if (sinkDevObj->TaskSetVolume(eventParam) != DH_SUCCESS) {
741 DHLOGE("Set volume failed.");
742 return;
743 }
744 }
745
NotifyVolumeChange(const AppExecFwk::InnerEvent::Pointer & event)746 void DAudioSinkDev::SinkEventHandler::NotifyVolumeChange(const AppExecFwk::InnerEvent::Pointer &event)
747 {
748 std::string eventParam;
749 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
750 DHLOGE("Failed to get event parameters.");
751 return;
752 }
753 auto sinkDevObj = sinkDev_.lock();
754 CHECK_NULL_VOID(sinkDevObj);
755
756 if (sinkDevObj->TaskVolumeChange(eventParam) != DH_SUCCESS) {
757 DHLOGE("Notify volume change status to source device failed.");
758 return;
759 }
760 }
761
NotifySetParam(const AppExecFwk::InnerEvent::Pointer & event)762 void DAudioSinkDev::SinkEventHandler::NotifySetParam(const AppExecFwk::InnerEvent::Pointer &event)
763 {
764 std::string eventParam;
765 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
766 DHLOGE("Failed to get event parameters.");
767 return;
768 }
769 auto sinkDevObj = sinkDev_.lock();
770 CHECK_NULL_VOID(sinkDevObj);
771
772 if (sinkDevObj->TaskSetParameter(eventParam) != DH_SUCCESS) {
773 DHLOGE("Set parameters failed.");
774 return;
775 }
776 }
777
NotifySetMute(const AppExecFwk::InnerEvent::Pointer & event)778 void DAudioSinkDev::SinkEventHandler::NotifySetMute(const AppExecFwk::InnerEvent::Pointer &event)
779 {
780 std::string eventParam;
781 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
782 DHLOGE("Failed to get event parameters.");
783 return;
784 }
785 auto sinkDevObj = sinkDev_.lock();
786 CHECK_NULL_VOID(sinkDevObj);
787
788 if (sinkDevObj->TaskSetMute(eventParam) != DH_SUCCESS) {
789 DHLOGE("Set mute failed.");
790 return;
791 }
792 }
793
NotifyFocusChange(const AppExecFwk::InnerEvent::Pointer & event)794 void DAudioSinkDev::SinkEventHandler::NotifyFocusChange(const AppExecFwk::InnerEvent::Pointer &event)
795 {
796 std::string eventParam;
797 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
798 DHLOGE("Failed to get event parameters.");
799 return;
800 }
801 auto sinkDevObj = sinkDev_.lock();
802 CHECK_NULL_VOID(sinkDevObj);
803
804 if (sinkDevObj->TaskFocusChange(eventParam) != DH_SUCCESS) {
805 DHLOGE("Handle focus change event failed.");
806 return;
807 }
808 }
809
NotifyRenderStateChange(const AppExecFwk::InnerEvent::Pointer & event)810 void DAudioSinkDev::SinkEventHandler::NotifyRenderStateChange(const AppExecFwk::InnerEvent::Pointer &event)
811 {
812 std::string eventParam;
813 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
814 DHLOGE("Failed to get event parameters.");
815 return;
816 }
817 auto sinkDevObj = sinkDev_.lock();
818 CHECK_NULL_VOID(sinkDevObj);
819
820 if (sinkDevObj->TaskRenderStateChange(eventParam) != DH_SUCCESS) {
821 DHLOGE("Handle render state change failed.");
822 return;
823 }
824 }
825
NotifyPlayStatusChange(const AppExecFwk::InnerEvent::Pointer & event)826 void DAudioSinkDev::SinkEventHandler::NotifyPlayStatusChange(const AppExecFwk::InnerEvent::Pointer &event)
827 {
828 std::string eventParam;
829 if (GetEventParam(event, eventParam) != DH_SUCCESS) {
830 DHLOGE("Failed to get event parameters.");
831 return;
832 }
833 auto sinkDevObj = sinkDev_.lock();
834 CHECK_NULL_VOID(sinkDevObj);
835
836 if (sinkDevObj->TaskPlayStatusChange(eventParam) != DH_SUCCESS) {
837 DHLOGE("Handle play status change event failed.");
838 return;
839 }
840 }
841
GetEventParam(const AppExecFwk::InnerEvent::Pointer & event,std::string & eventParam)842 int32_t DAudioSinkDev::SinkEventHandler::GetEventParam(const AppExecFwk::InnerEvent::Pointer &event,
843 std::string &eventParam)
844 {
845 CHECK_NULL_RETURN(event, ERR_DH_AUDIO_NULLPTR);
846 std::shared_ptr<AudioEvent> paramObj = event->GetSharedObject<AudioEvent>();
847 CHECK_NULL_RETURN(paramObj, ERR_DH_AUDIO_NULLPTR);
848 eventParam = paramObj->content;
849 return DH_SUCCESS;
850 }
851
PauseDistributedHardware(const std::string & networkId)852 int32_t DAudioSinkDev::PauseDistributedHardware(const std::string &networkId)
853 {
854 DHLOGI("DAudioSinkDev PauseDistributedHardware.");
855 int32_t dhId = ConvertString2Int(micDhId_);
856 std::shared_ptr<DMicClient> micClient = nullptr;
857 {
858 std::lock_guard<std::mutex> devLck(micClientMutex_);
859 micClient = micClientMap_[dhId];
860 }
861
862 CHECK_NULL_RETURN(micClient, ERR_DH_AUDIO_NULLPTR);
863 int32_t ret = micClient->PauseCapture();
864 if (ret != DH_SUCCESS) {
865 DHLOGE("Pause mic client failed, ret: %d.", ret);
866 }
867 return ret;
868 }
869
ResumeDistributedHardware(const std::string & networkId)870 int32_t DAudioSinkDev::ResumeDistributedHardware(const std::string &networkId)
871 {
872 DHLOGI("DAudioSinkDev ResumeDistributedHardware.");
873 int32_t dhId = ConvertString2Int(micDhId_);
874 std::shared_ptr<DMicClient> micClient = nullptr;
875 {
876 std::lock_guard<std::mutex> devLck(micClientMutex_);
877 micClient = micClientMap_[dhId];
878 }
879
880 CHECK_NULL_RETURN(micClient, ERR_DH_AUDIO_NULLPTR);
881 int32_t ret = micClient->ResumeCapture();
882 if (ret != DH_SUCCESS) {
883 DHLOGE("Resume mic client failed, ret: %d.", ret);
884 }
885 return ret;
886 }
887
StopDistributedHardware(const std::string & networkId)888 int32_t DAudioSinkDev::StopDistributedHardware(const std::string &networkId)
889 {
890 DHLOGI("DAudioSinkDev StopDistributedHardware.");
891 isPageStatus_.store(false);
892 NotifySourceDev(CLOSE_MIC, micDhId_, DH_SUCCESS);
893 return DH_SUCCESS;
894 }
895 } // namespace DistributedHardware
896 } // namespace OHOS
897