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 "OHAudioRoutingManager.h"
17 
18 #include <set>
19 
20 #include "audio_errors.h"
21 #include "audio_routing_manager.h"
22 #include "parameters.h"
23 
24 namespace {
25 const size_t MAX_VALID_SIZE = 128; // MAX AudioDevice size.
26 const std::set<OH_AudioDevice_Usage> VALID_OH_AUDIO_DEVICE_UASGES = {
27     AUDIO_DEVICE_USAGE_MEDIA_OUTPUT,
28     AUDIO_DEVICE_USAGE_MEDIA_INPUT,
29     AUDIO_DEVICE_USAGE_MEDIA_ALL,
30     AUDIO_DEVICE_USAGE_CALL_OUTPUT,
31     AUDIO_DEVICE_USAGE_CALL_INPUT,
32     AUDIO_DEVICE_USAGE_CALL_ALL
33 };
34 const std::set<OH_AudioStream_Usage> VALID_OH_STREAM_USAGES = {
35     AUDIOSTREAM_USAGE_UNKNOWN,
36     AUDIOSTREAM_USAGE_MUSIC,
37     AUDIOSTREAM_USAGE_VOICE_COMMUNICATION,
38     AUDIOSTREAM_USAGE_VOICE_ASSISTANT,
39     AUDIOSTREAM_USAGE_ALARM,
40     AUDIOSTREAM_USAGE_VOICE_MESSAGE,
41     AUDIOSTREAM_USAGE_RINGTONE,
42     AUDIOSTREAM_USAGE_NOTIFICATION,
43     AUDIOSTREAM_USAGE_ACCESSIBILITY,
44     AUDIOSTREAM_USAGE_MOVIE,
45     AUDIOSTREAM_USAGE_GAME,
46     AUDIOSTREAM_USAGE_AUDIOBOOK,
47     AUDIOSTREAM_USAGE_NAVIGATION,
48     AUDIOSTREAM_USAGE_VIDEO_COMMUNICATION
49 };
50 const std::set<OH_AudioStream_SourceType> VALID_OH_SOURCE_TYPES = {
51     AUDIOSTREAM_SOURCE_TYPE_MIC,
52     AUDIOSTREAM_SOURCE_TYPE_VOICE_RECOGNITION,
53     AUDIOSTREAM_SOURCE_TYPE_PLAYBACK_CAPTURE,
54     AUDIOSTREAM_SOURCE_TYPE_VOICE_COMMUNICATION,
55     AUDIOSTREAM_SOURCE_TYPE_VOICE_MESSAGE
56 };
57 }
58 
59 using OHOS::AudioStandard::OHAudioRoutingManager;
60 using OHOS::AudioStandard::OHAudioDeviceDescriptor;
61 using OHOS::AudioStandard::AudioRoutingManager;
62 using OHOS::AudioStandard::DeviceFlag;
63 using OHOS::AudioStandard::AudioDeviceUsage;
64 using OHOS::AudioStandard::StreamUsage;
65 using OHOS::AudioStandard::SourceType;
66 
convertManager(OH_AudioRoutingManager * manager)67 static OHOS::AudioStandard::OHAudioRoutingManager *convertManager(OH_AudioRoutingManager* manager)
68 {
69     return (OHAudioRoutingManager*) manager;
70 }
71 
OH_AudioManager_GetAudioRoutingManager(OH_AudioRoutingManager ** audioRoutingManager)72 OH_AudioCommon_Result OH_AudioManager_GetAudioRoutingManager(OH_AudioRoutingManager **audioRoutingManager)
73 {
74     OHAudioRoutingManager* ohAudioRoutingManager = OHAudioRoutingManager::GetInstance();
75     *audioRoutingManager = (OH_AudioRoutingManager*)ohAudioRoutingManager;
76     return AUDIOCOMMON_RESULT_SUCCESS;
77 }
78 
OH_AudioRoutingManager_GetDevices(OH_AudioRoutingManager * audioRoutingManager,OH_AudioDevice_Flag deviceFlag,OH_AudioDeviceDescriptorArray ** audioDeviceDescriptorArray)79 OH_AudioCommon_Result OH_AudioRoutingManager_GetDevices(OH_AudioRoutingManager *audioRoutingManager,
80     OH_AudioDevice_Flag deviceFlag, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
81 {
82     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
83     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
84         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "ohAudioRoutingManager is nullptr");
85     CHECK_AND_RETURN_RET_LOG((
86         deviceFlag == AUDIO_DEVICE_FLAG_NONE ||
87         deviceFlag == AUDIO_DEVICE_FLAG_OUTPUT ||
88         deviceFlag == AUDIO_DEVICE_FLAG_INPUT ||
89         deviceFlag == AUDIO_DEVICE_FLAG_ALL),
90         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "deviceFlag is invalid");
91     CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptorArray != nullptr,
92         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptorArray is nullptr");
93     DeviceFlag flag = static_cast<DeviceFlag>(deviceFlag);
94     *audioDeviceDescriptorArray = ohAudioRoutingManager->GetDevices(flag);
95     CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
96         AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
97     return AUDIOCOMMON_RESULT_SUCCESS;
98 }
99 
OH_AudioRoutingManager_GetAvailableDevices(OH_AudioRoutingManager * audioRoutingManager,OH_AudioDevice_Usage deviceUsage,OH_AudioDeviceDescriptorArray ** audioDeviceDescriptorArray)100 OH_AudioCommon_Result OH_AudioRoutingManager_GetAvailableDevices(OH_AudioRoutingManager *audioRoutingManager,
101     OH_AudioDevice_Usage deviceUsage, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
102 {
103     if (audioRoutingManager == nullptr || !VALID_OH_AUDIO_DEVICE_UASGES.count(deviceUsage) ||
104         audioDeviceDescriptorArray == nullptr) {
105         AUDIO_ERR_LOG("Invalid params!");
106         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
107     }
108     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
109     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
110         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
111 
112     AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(deviceUsage);
113     *audioDeviceDescriptorArray = ohAudioRoutingManager->GetAvailableDevices(usage);
114     CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
115         AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
116 
117     return AUDIOCOMMON_RESULT_SUCCESS;
118 }
119 
OH_AudioRoutingManager_GetPreferredOutputDevice(OH_AudioRoutingManager * audioRoutingManager,OH_AudioStream_Usage streamUsage,OH_AudioDeviceDescriptorArray ** audioDeviceDescriptorArray)120 OH_AudioCommon_Result OH_AudioRoutingManager_GetPreferredOutputDevice(OH_AudioRoutingManager *audioRoutingManager,
121     OH_AudioStream_Usage streamUsage, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
122 {
123     if (audioRoutingManager == nullptr || !VALID_OH_STREAM_USAGES.count(streamUsage) ||
124         audioDeviceDescriptorArray == nullptr) {
125         AUDIO_ERR_LOG("Invalid params!");
126         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
127     }
128     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
129     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
130         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
131 
132     StreamUsage usage = static_cast<StreamUsage>(streamUsage);
133     *audioDeviceDescriptorArray = ohAudioRoutingManager->GetPreferredOutputDevice(usage);
134     CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
135         AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
136 
137     return AUDIOCOMMON_RESULT_SUCCESS;
138 }
139 
OH_AudioRoutingManager_GetPreferredInputDevice(OH_AudioRoutingManager * audioRoutingManager,OH_AudioStream_SourceType sourceType,OH_AudioDeviceDescriptorArray ** audioDeviceDescriptorArray)140 OH_AudioCommon_Result OH_AudioRoutingManager_GetPreferredInputDevice(OH_AudioRoutingManager *audioRoutingManager,
141     OH_AudioStream_SourceType sourceType, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
142 {
143     if (audioRoutingManager == nullptr || !VALID_OH_SOURCE_TYPES.count(sourceType) ||
144         audioDeviceDescriptorArray == nullptr) {
145         AUDIO_ERR_LOG("Invalid params!");
146         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
147     }
148     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
149     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
150         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
151 
152     SourceType type = static_cast<SourceType>(sourceType);
153     *audioDeviceDescriptorArray = ohAudioRoutingManager->GetPreferredInputDevice(type);
154     CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
155         AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
156 
157     return AUDIOCOMMON_RESULT_SUCCESS;
158 }
159 
OH_AudioRoutingManager_RegisterDeviceChangeCallback(OH_AudioRoutingManager * audioRoutingManager,OH_AudioDevice_Flag deviceFlag,OH_AudioRoutingManager_OnDeviceChangedCallback callback)160 OH_AudioCommon_Result OH_AudioRoutingManager_RegisterDeviceChangeCallback(
161     OH_AudioRoutingManager *audioRoutingManager, OH_AudioDevice_Flag deviceFlag,
162     OH_AudioRoutingManager_OnDeviceChangedCallback callback)
163 {
164     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
165     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
166         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
167     CHECK_AND_RETURN_RET_LOG((
168         deviceFlag == AUDIO_DEVICE_FLAG_NONE ||
169         deviceFlag == AUDIO_DEVICE_FLAG_OUTPUT ||
170         deviceFlag == AUDIO_DEVICE_FLAG_INPUT ||
171         deviceFlag == AUDIO_DEVICE_FLAG_ALL),
172         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "deviceFlag is invalid");
173     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "callback is nullptr");
174     DeviceFlag flag = static_cast<DeviceFlag>(deviceFlag);
175     ohAudioRoutingManager->SetDeviceChangeCallback(flag, callback);
176     return AUDIOCOMMON_RESULT_SUCCESS;
177 }
178 
OH_AudioRoutingManager_UnregisterDeviceChangeCallback(OH_AudioRoutingManager * audioRoutingManager,OH_AudioRoutingManager_OnDeviceChangedCallback callback)179 OH_AudioCommon_Result OH_AudioRoutingManager_UnregisterDeviceChangeCallback(
180     OH_AudioRoutingManager *audioRoutingManager,
181     OH_AudioRoutingManager_OnDeviceChangedCallback callback)
182 {
183     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
184     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
185         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
186     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "callback is nullptr");
187     DeviceFlag flag = static_cast<DeviceFlag>(AUDIO_DEVICE_FLAG_ALL);
188     ohAudioRoutingManager->UnsetDeviceChangeCallback(flag, callback);
189     return AUDIOCOMMON_RESULT_SUCCESS;
190 }
191 
OH_AudioRoutingManager_ReleaseDevices(OH_AudioRoutingManager * audioRoutingManager,OH_AudioDeviceDescriptorArray * audioDeviceDescriptorArray)192 OH_AudioCommon_Result OH_AudioRoutingManager_ReleaseDevices(
193     OH_AudioRoutingManager *audioRoutingManager,
194     OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray)
195 {
196     OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
197     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
198         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
199     CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptorArray != nullptr,
200         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptorArray is nullptr");
201     if (audioDeviceDescriptorArray == nullptr) {
202         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
203     }
204     for (uint32_t index = 0; index < audioDeviceDescriptorArray->size; index++) {
205         OHAudioDeviceDescriptor* ohAudioDeviceDescriptor =
206             (OHAudioDeviceDescriptor*)audioDeviceDescriptorArray->descriptors[index];
207         delete ohAudioDeviceDescriptor;
208         audioDeviceDescriptorArray->descriptors[index] = nullptr;
209     }
210     free(audioDeviceDescriptorArray->descriptors);
211     audioDeviceDescriptorArray->descriptors = nullptr;
212     free(audioDeviceDescriptorArray);
213     audioDeviceDescriptorArray = nullptr;
214     return AUDIOCOMMON_RESULT_SUCCESS;
215 }
216 
OH_AudioRoutingManager_IsMicBlockDetectionSupported(OH_AudioRoutingManager * audioRoutingManager,bool * supported)217 OH_AudioCommon_Result OH_AudioRoutingManager_IsMicBlockDetectionSupported(
218     OH_AudioRoutingManager *audioRoutingManager, bool *supported)
219 {
220     if (audioRoutingManager == nullptr || supported == nullptr) {
221         AUDIO_ERR_LOG("params is nullptr");
222         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
223     }
224     *supported = OHOS::system::GetBoolParameter("const.multimedia.audio.mic_block_detection", false);
225     if (*supported == true) {
226         AUDIO_INFO_LOG("mic block detection supported");
227     } else {
228         AUDIO_INFO_LOG("mic block detection is not supported");
229     }
230     return AUDIOCOMMON_RESULT_SUCCESS;
231 }
232 
OH_AudioRoutingManager_SetMicBlockStatusCallback(OH_AudioRoutingManager * audioRoutingManager,OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback,void * userData)233 OH_AudioCommon_Result OH_AudioRoutingManager_SetMicBlockStatusCallback(
234     OH_AudioRoutingManager *audioRoutingManager,
235     OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback, void *userData)
236 {
237     OHAudioRoutingManager *ohAudioRoutingManager = convertManager(audioRoutingManager);
238     CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
239         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
240     ohAudioRoutingManager->SetMicrophoneBlockedCallback(callback, userData);
241     return AUDIOCOMMON_RESULT_SUCCESS;
242 }
243 
244 namespace OHOS {
245 namespace AudioStandard {
246 
DestroyAudioDeviceDescriptor(OH_AudioDeviceDescriptorArray * array)247 void DestroyAudioDeviceDescriptor(OH_AudioDeviceDescriptorArray *array)
248 {
249     if (array) {
250         for (uint32_t index = 0; index < array->size; index++) {
251             OHAudioDeviceDescriptor* ohAudioDeviceDescriptor = (OHAudioDeviceDescriptor*)array->descriptors[index];
252             delete ohAudioDeviceDescriptor;
253             array->descriptors[index] = nullptr;
254         }
255         free(array->descriptors);
256         free(array);
257     }
258 }
259 
OHAudioRoutingManager()260 OHAudioRoutingManager::OHAudioRoutingManager()
261 {
262     AUDIO_INFO_LOG("OHAudioRoutingManager created!");
263 }
264 
~OHAudioRoutingManager()265 OHAudioRoutingManager::~OHAudioRoutingManager()
266 {
267     AUDIO_INFO_LOG("OHAudioRoutingManager destroyed!");
268 }
269 
ConvertDesc(std::vector<sptr<AudioDeviceDescriptor>> & desc)270 OH_AudioDeviceDescriptorArray *OHAudioRoutingManager::ConvertDesc(std::vector<sptr<AudioDeviceDescriptor>> &desc)
271 {
272     size_t size = desc.size();
273     if (size == 0 || size >= MAX_VALID_SIZE) {
274         AUDIO_ERR_LOG("failed to convert device info, size is %{public}zu", size);
275         return nullptr;
276     }
277 
278     OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
279         (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
280 
281     if (audioDeviceDescriptorArray == nullptr) {
282         AUDIO_ERR_LOG("failed to malloc.");
283         return nullptr;
284     }
285     audioDeviceDescriptorArray->size = 0;
286     audioDeviceDescriptorArray->descriptors =
287         (OH_AudioDeviceDescriptor **)malloc(sizeof(OH_AudioDeviceDescriptor *) * size);
288     if (audioDeviceDescriptorArray->descriptors == nullptr) {
289         free(audioDeviceDescriptorArray);
290         audioDeviceDescriptorArray = nullptr;
291         AUDIO_ERR_LOG("failed to malloc descriptors.");
292         return nullptr;
293     }
294 
295     uint32_t index = 0;
296     for (auto deviceDescriptor : desc) {
297         audioDeviceDescriptorArray->descriptors[index] =
298             (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
299         if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
300             DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
301             return nullptr;
302         }
303         index++;
304         audioDeviceDescriptorArray->size = index;
305     }
306     return audioDeviceDescriptorArray;
307 }
308 
GetDevices(DeviceFlag deviceFlag)309 OH_AudioDeviceDescriptorArray* OHAudioRoutingManager::GetDevices(DeviceFlag deviceFlag)
310 {
311     CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
312         nullptr, "failed, audioSystemManager is null");
313     std::vector<sptr<AudioDeviceDescriptor>> audioDeviceDescriptors = audioSystemManager_->GetDevices(deviceFlag);
314     uint32_t size = audioDeviceDescriptors.size();
315     if (size <= 0) {
316         AUDIO_ERR_LOG("audioDeviceDescriptors is null");
317         return nullptr;
318     }
319     return ConvertDesc(audioDeviceDescriptors);
320 }
321 
GetAvailableDevices(AudioDeviceUsage deviceUsage)322 OH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetAvailableDevices(AudioDeviceUsage deviceUsage)
323 {
324     std::vector<std::unique_ptr<AudioDeviceDescriptor>> tempDesc =
325         AudioRoutingManager::GetInstance()->GetAvailableDevices(deviceUsage);
326     if (tempDesc.size() == 0) {
327         AUDIO_ERR_LOG("get no device");
328         return nullptr;
329     }
330     std::vector<sptr<AudioDeviceDescriptor>> altaDesc = {};
331     for (const auto &availableDesc : tempDesc) {
332         sptr<AudioDeviceDescriptor> dec = new(std::nothrow) AudioDeviceDescriptor(*availableDesc);
333         altaDesc.push_back(dec);
334     }
335     return ConvertDesc(altaDesc);
336 }
337 
GetPreferredOutputDevice(StreamUsage streamUsage)338 OH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetPreferredOutputDevice(StreamUsage streamUsage)
339 {
340     AudioRendererInfo rendererInfo = {};
341     rendererInfo.streamUsage = streamUsage;
342     std::vector<sptr<AudioDeviceDescriptor>> desc = {};
343 
344     int32_t ret = AudioRoutingManager::GetInstance()->GetPreferredOutputDeviceForRendererInfo(rendererInfo, desc);
345     if (ret != SUCCESS) {
346         AUDIO_ERR_LOG("call failed!");
347         return nullptr;
348     }
349     return ConvertDesc(desc);
350 }
351 
GetPreferredInputDevice(SourceType sourceType)352 OH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetPreferredInputDevice(SourceType sourceType)
353 {
354     AudioCapturerInfo capturerInfo = {};
355     capturerInfo.sourceType = sourceType;
356     std::vector<sptr<AudioDeviceDescriptor>> desc = {};
357 
358     int32_t ret = AudioRoutingManager::GetInstance()->GetPreferredInputDeviceForCapturerInfo(capturerInfo, desc);
359     if (ret != SUCCESS) {
360         AUDIO_ERR_LOG("call failed!");
361         return nullptr;
362     }
363     return ConvertDesc(desc);
364 }
365 
SetDeviceChangeCallback(const DeviceFlag deviceFlag,OH_AudioRoutingManager_OnDeviceChangedCallback callback)366 OH_AudioCommon_Result OHAudioRoutingManager::SetDeviceChangeCallback(const DeviceFlag deviceFlag,
367     OH_AudioRoutingManager_OnDeviceChangedCallback callback)
368 {
369     CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
370         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
371     std::shared_ptr<OHAudioDeviceChangedCallback> ohAudioOnDeviceChangedCallback =
372         std::make_shared<OHAudioDeviceChangedCallback>(callback);
373     if (ohAudioOnDeviceChangedCallback) {
374         audioSystemManager_->SetDeviceChangeCallback(deviceFlag, ohAudioOnDeviceChangedCallback);
375         ohAudioOnDeviceChangedCallbackArray_.push_back(ohAudioOnDeviceChangedCallback);
376         return AUDIOCOMMON_RESULT_SUCCESS;
377     }
378     return AUDIOCOMMON_RESULT_ERROR_NO_MEMORY;
379 }
380 
UnsetDeviceChangeCallback(DeviceFlag deviceFlag,OH_AudioRoutingManager_OnDeviceChangedCallback ohOnDeviceChangedcallback)381 OH_AudioCommon_Result OHAudioRoutingManager::UnsetDeviceChangeCallback(DeviceFlag deviceFlag,
382     OH_AudioRoutingManager_OnDeviceChangedCallback ohOnDeviceChangedcallback)
383 {
384     CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
385         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
386     auto iter = std::find_if(ohAudioOnDeviceChangedCallbackArray_.begin(), ohAudioOnDeviceChangedCallbackArray_.end(),
387         [&](const std::shared_ptr<OHAudioDeviceChangedCallback> &item) {
388         return item->GetCallback() == ohOnDeviceChangedcallback;
389     });
390     if (iter == ohAudioOnDeviceChangedCallbackArray_.end()) {
391         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
392     }
393     audioSystemManager_->UnsetDeviceChangeCallback(deviceFlag);
394     ohAudioOnDeviceChangedCallbackArray_.erase(iter);
395     return AUDIOCOMMON_RESULT_SUCCESS;
396 }
397 
OnDeviceChange(const DeviceChangeAction & deviceChangeAction)398 void OHAudioDeviceChangedCallback::OnDeviceChange(const DeviceChangeAction &deviceChangeAction)
399 {
400     CHECK_AND_RETURN_LOG(callback_ != nullptr, "failed, pointer to the fuction is nullptr");
401     OH_AudioDevice_ChangeType type = static_cast<OH_AudioDevice_ChangeType>(deviceChangeAction.type);
402     uint32_t size = deviceChangeAction.deviceDescriptors.size();
403     if (size <= 0) {
404         AUDIO_ERR_LOG("audioDeviceDescriptors is null");
405         return;
406     }
407 
408     OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
409         (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
410     if (audioDeviceDescriptorArray) {
411         audioDeviceDescriptorArray->descriptors =
412             (OH_AudioDeviceDescriptor**)malloc(sizeof(OH_AudioDeviceDescriptor*) * size);
413         if (audioDeviceDescriptorArray->descriptors == nullptr) {
414             free(audioDeviceDescriptorArray);
415             audioDeviceDescriptorArray = nullptr;
416             AUDIO_ERR_LOG("failed to malloc descriptors.");
417             return;
418         }
419         audioDeviceDescriptorArray->size = size;
420         uint32_t index = 0;
421         for (auto deviceDescriptor : deviceChangeAction.deviceDescriptors) {
422             audioDeviceDescriptorArray->descriptors[index] =
423                 (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
424             if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
425                 DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
426                 return;
427             }
428             index++;
429         }
430     }
431     callback_(type, audioDeviceDescriptorArray);
432 }
433 
OnMicrophoneBlocked(const MicrophoneBlockedInfo & microphoneBlockedInfo)434 void OHMicrophoneBlockCallback::OnMicrophoneBlocked(const MicrophoneBlockedInfo &microphoneBlockedInfo)
435 {
436     AUDIO_INFO_LOG("Enter blocked info: %{public}d", microphoneBlockedInfo.blockStatus);
437     CHECK_AND_RETURN_LOG(blockedCallback_ != nullptr, "failed, pointer to the fuction is nullptr");
438     uint32_t size = microphoneBlockedInfo.devices.size();
439     if (size <= 0) {
440         AUDIO_ERR_LOG("audioDeviceDescriptors is null");
441         return;
442     }
443     OH_AudioDevice_BlockStatus status = static_cast<OH_AudioDevice_BlockStatus>(microphoneBlockedInfo.blockStatus);
444     OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
445         (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
446     if (audioDeviceDescriptorArray) {
447         audioDeviceDescriptorArray->descriptors =
448             (OH_AudioDeviceDescriptor**)malloc(sizeof(OH_AudioDeviceDescriptor*) * size);
449         if (audioDeviceDescriptorArray->descriptors == nullptr) {
450             free(audioDeviceDescriptorArray);
451             audioDeviceDescriptorArray = nullptr;
452             AUDIO_ERR_LOG("failed to malloc descriptors.");
453             return;
454         }
455         audioDeviceDescriptorArray->size = size;
456         uint32_t index = 0;
457         for (auto deviceDescriptor : microphoneBlockedInfo.devices) {
458             audioDeviceDescriptorArray->descriptors[index] =
459                 (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
460             if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
461                 DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
462                 return;
463             }
464             index++;
465         }
466     }
467     blockedCallback_(audioDeviceDescriptorArray, status, nullptr);
468 }
469 
SetMicrophoneBlockedCallback(OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback,void * userData)470 OH_AudioCommon_Result OHAudioRoutingManager::SetMicrophoneBlockedCallback(
471     OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback, void *userData)
472 {
473     CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
474         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
475     if (callback == nullptr) {
476         UnsetMicrophoneBlockedCallback(callback);
477         return AUDIOCOMMON_RESULT_SUCCESS;
478     }
479     std::shared_ptr<OHMicrophoneBlockCallback> microphoneBlock =
480         std::make_shared<OHMicrophoneBlockCallback>(callback, userData);
481     audioSystemManager_->SetMicrophoneBlockedCallback(microphoneBlock);
482     ohMicroPhoneBlockCallbackArray_.push_back(microphoneBlock);
483     return AUDIOCOMMON_RESULT_SUCCESS;
484 }
485 
UnsetMicrophoneBlockedCallback(OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback)486 OH_AudioCommon_Result OHAudioRoutingManager::UnsetMicrophoneBlockedCallback(
487     OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback)
488 {
489     CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
490         AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
491 
492     audioSystemManager_->UnsetMicrophoneBlockedCallback();
493 
494     auto iter = std::find_if(ohMicroPhoneBlockCallbackArray_.begin(), ohMicroPhoneBlockCallbackArray_.end(),
495         [&](const std::shared_ptr<OHMicrophoneBlockCallback> &item) {
496         return item->GetCallback() == callback;
497     });
498     if (iter == ohMicroPhoneBlockCallbackArray_.end()) {
499         return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
500     }
501 
502     ohMicroPhoneBlockCallbackArray_.erase(iter);
503     return AUDIOCOMMON_RESULT_SUCCESS;
504 }
505 }  // namespace AudioStandard
506 }  // namespace OHOS