146f34cbfSopenharmony_ci/*
246f34cbfSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
346f34cbfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
446f34cbfSopenharmony_ci * you may not use this file except in compliance with the License.
546f34cbfSopenharmony_ci * You may obtain a copy of the License at
646f34cbfSopenharmony_ci *
746f34cbfSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
846f34cbfSopenharmony_ci *
946f34cbfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1046f34cbfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1146f34cbfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1246f34cbfSopenharmony_ci * See the License for the specific language governing permissions and
1346f34cbfSopenharmony_ci * limitations under the License.
1446f34cbfSopenharmony_ci */
1546f34cbfSopenharmony_ci
1646f34cbfSopenharmony_ci#include "OHAudioRoutingManager.h"
1746f34cbfSopenharmony_ci
1846f34cbfSopenharmony_ci#include <set>
1946f34cbfSopenharmony_ci
2046f34cbfSopenharmony_ci#include "audio_errors.h"
2146f34cbfSopenharmony_ci#include "audio_routing_manager.h"
2246f34cbfSopenharmony_ci#include "parameters.h"
2346f34cbfSopenharmony_ci
2446f34cbfSopenharmony_cinamespace {
2546f34cbfSopenharmony_ciconst size_t MAX_VALID_SIZE = 128; // MAX AudioDevice size.
2646f34cbfSopenharmony_ciconst std::set<OH_AudioDevice_Usage> VALID_OH_AUDIO_DEVICE_UASGES = {
2746f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_MEDIA_OUTPUT,
2846f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_MEDIA_INPUT,
2946f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_MEDIA_ALL,
3046f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_CALL_OUTPUT,
3146f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_CALL_INPUT,
3246f34cbfSopenharmony_ci    AUDIO_DEVICE_USAGE_CALL_ALL
3346f34cbfSopenharmony_ci};
3446f34cbfSopenharmony_ciconst std::set<OH_AudioStream_Usage> VALID_OH_STREAM_USAGES = {
3546f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_UNKNOWN,
3646f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_MUSIC,
3746f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_VOICE_COMMUNICATION,
3846f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_VOICE_ASSISTANT,
3946f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_ALARM,
4046f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_VOICE_MESSAGE,
4146f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_RINGTONE,
4246f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_NOTIFICATION,
4346f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_ACCESSIBILITY,
4446f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_MOVIE,
4546f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_GAME,
4646f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_AUDIOBOOK,
4746f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_NAVIGATION,
4846f34cbfSopenharmony_ci    AUDIOSTREAM_USAGE_VIDEO_COMMUNICATION
4946f34cbfSopenharmony_ci};
5046f34cbfSopenharmony_ciconst std::set<OH_AudioStream_SourceType> VALID_OH_SOURCE_TYPES = {
5146f34cbfSopenharmony_ci    AUDIOSTREAM_SOURCE_TYPE_MIC,
5246f34cbfSopenharmony_ci    AUDIOSTREAM_SOURCE_TYPE_VOICE_RECOGNITION,
5346f34cbfSopenharmony_ci    AUDIOSTREAM_SOURCE_TYPE_PLAYBACK_CAPTURE,
5446f34cbfSopenharmony_ci    AUDIOSTREAM_SOURCE_TYPE_VOICE_COMMUNICATION,
5546f34cbfSopenharmony_ci    AUDIOSTREAM_SOURCE_TYPE_VOICE_MESSAGE
5646f34cbfSopenharmony_ci};
5746f34cbfSopenharmony_ci}
5846f34cbfSopenharmony_ci
5946f34cbfSopenharmony_ciusing OHOS::AudioStandard::OHAudioRoutingManager;
6046f34cbfSopenharmony_ciusing OHOS::AudioStandard::OHAudioDeviceDescriptor;
6146f34cbfSopenharmony_ciusing OHOS::AudioStandard::AudioRoutingManager;
6246f34cbfSopenharmony_ciusing OHOS::AudioStandard::DeviceFlag;
6346f34cbfSopenharmony_ciusing OHOS::AudioStandard::AudioDeviceUsage;
6446f34cbfSopenharmony_ciusing OHOS::AudioStandard::StreamUsage;
6546f34cbfSopenharmony_ciusing OHOS::AudioStandard::SourceType;
6646f34cbfSopenharmony_ci
6746f34cbfSopenharmony_cistatic OHOS::AudioStandard::OHAudioRoutingManager *convertManager(OH_AudioRoutingManager* manager)
6846f34cbfSopenharmony_ci{
6946f34cbfSopenharmony_ci    return (OHAudioRoutingManager*) manager;
7046f34cbfSopenharmony_ci}
7146f34cbfSopenharmony_ci
7246f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioManager_GetAudioRoutingManager(OH_AudioRoutingManager **audioRoutingManager)
7346f34cbfSopenharmony_ci{
7446f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = OHAudioRoutingManager::GetInstance();
7546f34cbfSopenharmony_ci    *audioRoutingManager = (OH_AudioRoutingManager*)ohAudioRoutingManager;
7646f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
7746f34cbfSopenharmony_ci}
7846f34cbfSopenharmony_ci
7946f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_GetDevices(OH_AudioRoutingManager *audioRoutingManager,
8046f34cbfSopenharmony_ci    OH_AudioDevice_Flag deviceFlag, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
8146f34cbfSopenharmony_ci{
8246f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
8346f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
8446f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "ohAudioRoutingManager is nullptr");
8546f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG((
8646f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_NONE ||
8746f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_OUTPUT ||
8846f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_INPUT ||
8946f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_ALL),
9046f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "deviceFlag is invalid");
9146f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptorArray != nullptr,
9246f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptorArray is nullptr");
9346f34cbfSopenharmony_ci    DeviceFlag flag = static_cast<DeviceFlag>(deviceFlag);
9446f34cbfSopenharmony_ci    *audioDeviceDescriptorArray = ohAudioRoutingManager->GetDevices(flag);
9546f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
9646f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
9746f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
9846f34cbfSopenharmony_ci}
9946f34cbfSopenharmony_ci
10046f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_GetAvailableDevices(OH_AudioRoutingManager *audioRoutingManager,
10146f34cbfSopenharmony_ci    OH_AudioDevice_Usage deviceUsage, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
10246f34cbfSopenharmony_ci{
10346f34cbfSopenharmony_ci    if (audioRoutingManager == nullptr || !VALID_OH_AUDIO_DEVICE_UASGES.count(deviceUsage) ||
10446f34cbfSopenharmony_ci        audioDeviceDescriptorArray == nullptr) {
10546f34cbfSopenharmony_ci        AUDIO_ERR_LOG("Invalid params!");
10646f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
10746f34cbfSopenharmony_ci    }
10846f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
10946f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
11046f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
11146f34cbfSopenharmony_ci
11246f34cbfSopenharmony_ci    AudioDeviceUsage usage = static_cast<AudioDeviceUsage>(deviceUsage);
11346f34cbfSopenharmony_ci    *audioDeviceDescriptorArray = ohAudioRoutingManager->GetAvailableDevices(usage);
11446f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
11546f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
11646f34cbfSopenharmony_ci
11746f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
11846f34cbfSopenharmony_ci}
11946f34cbfSopenharmony_ci
12046f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_GetPreferredOutputDevice(OH_AudioRoutingManager *audioRoutingManager,
12146f34cbfSopenharmony_ci    OH_AudioStream_Usage streamUsage, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
12246f34cbfSopenharmony_ci{
12346f34cbfSopenharmony_ci    if (audioRoutingManager == nullptr || !VALID_OH_STREAM_USAGES.count(streamUsage) ||
12446f34cbfSopenharmony_ci        audioDeviceDescriptorArray == nullptr) {
12546f34cbfSopenharmony_ci        AUDIO_ERR_LOG("Invalid params!");
12646f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
12746f34cbfSopenharmony_ci    }
12846f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
12946f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
13046f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
13146f34cbfSopenharmony_ci
13246f34cbfSopenharmony_ci    StreamUsage usage = static_cast<StreamUsage>(streamUsage);
13346f34cbfSopenharmony_ci    *audioDeviceDescriptorArray = ohAudioRoutingManager->GetPreferredOutputDevice(usage);
13446f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
13546f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
13646f34cbfSopenharmony_ci
13746f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
13846f34cbfSopenharmony_ci}
13946f34cbfSopenharmony_ci
14046f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_GetPreferredInputDevice(OH_AudioRoutingManager *audioRoutingManager,
14146f34cbfSopenharmony_ci    OH_AudioStream_SourceType sourceType, OH_AudioDeviceDescriptorArray **audioDeviceDescriptorArray)
14246f34cbfSopenharmony_ci{
14346f34cbfSopenharmony_ci    if (audioRoutingManager == nullptr || !VALID_OH_SOURCE_TYPES.count(sourceType) ||
14446f34cbfSopenharmony_ci        audioDeviceDescriptorArray == nullptr) {
14546f34cbfSopenharmony_ci        AUDIO_ERR_LOG("Invalid params!");
14646f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
14746f34cbfSopenharmony_ci    }
14846f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
14946f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
15046f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
15146f34cbfSopenharmony_ci
15246f34cbfSopenharmony_ci    SourceType type = static_cast<SourceType>(sourceType);
15346f34cbfSopenharmony_ci    *audioDeviceDescriptorArray = ohAudioRoutingManager->GetPreferredInputDevice(type);
15446f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(*audioDeviceDescriptorArray != nullptr,
15546f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_NO_MEMORY, "*audioDeviceDescriptorArray is nullptr");
15646f34cbfSopenharmony_ci
15746f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
15846f34cbfSopenharmony_ci}
15946f34cbfSopenharmony_ci
16046f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_RegisterDeviceChangeCallback(
16146f34cbfSopenharmony_ci    OH_AudioRoutingManager *audioRoutingManager, OH_AudioDevice_Flag deviceFlag,
16246f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceChangedCallback callback)
16346f34cbfSopenharmony_ci{
16446f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
16546f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
16646f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
16746f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG((
16846f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_NONE ||
16946f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_OUTPUT ||
17046f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_INPUT ||
17146f34cbfSopenharmony_ci        deviceFlag == AUDIO_DEVICE_FLAG_ALL),
17246f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "deviceFlag is invalid");
17346f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(callback != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "callback is nullptr");
17446f34cbfSopenharmony_ci    DeviceFlag flag = static_cast<DeviceFlag>(deviceFlag);
17546f34cbfSopenharmony_ci    ohAudioRoutingManager->SetDeviceChangeCallback(flag, callback);
17646f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
17746f34cbfSopenharmony_ci}
17846f34cbfSopenharmony_ci
17946f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_UnregisterDeviceChangeCallback(
18046f34cbfSopenharmony_ci    OH_AudioRoutingManager *audioRoutingManager,
18146f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceChangedCallback callback)
18246f34cbfSopenharmony_ci{
18346f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
18446f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
18546f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
18646f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(callback != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "callback is nullptr");
18746f34cbfSopenharmony_ci    DeviceFlag flag = static_cast<DeviceFlag>(AUDIO_DEVICE_FLAG_ALL);
18846f34cbfSopenharmony_ci    ohAudioRoutingManager->UnsetDeviceChangeCallback(flag, callback);
18946f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
19046f34cbfSopenharmony_ci}
19146f34cbfSopenharmony_ci
19246f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_ReleaseDevices(
19346f34cbfSopenharmony_ci    OH_AudioRoutingManager *audioRoutingManager,
19446f34cbfSopenharmony_ci    OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray)
19546f34cbfSopenharmony_ci{
19646f34cbfSopenharmony_ci    OHAudioRoutingManager* ohAudioRoutingManager = convertManager(audioRoutingManager);
19746f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
19846f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
19946f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptorArray != nullptr,
20046f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptorArray is nullptr");
20146f34cbfSopenharmony_ci    if (audioDeviceDescriptorArray == nullptr) {
20246f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
20346f34cbfSopenharmony_ci    }
20446f34cbfSopenharmony_ci    for (uint32_t index = 0; index < audioDeviceDescriptorArray->size; index++) {
20546f34cbfSopenharmony_ci        OHAudioDeviceDescriptor* ohAudioDeviceDescriptor =
20646f34cbfSopenharmony_ci            (OHAudioDeviceDescriptor*)audioDeviceDescriptorArray->descriptors[index];
20746f34cbfSopenharmony_ci        delete ohAudioDeviceDescriptor;
20846f34cbfSopenharmony_ci        audioDeviceDescriptorArray->descriptors[index] = nullptr;
20946f34cbfSopenharmony_ci    }
21046f34cbfSopenharmony_ci    free(audioDeviceDescriptorArray->descriptors);
21146f34cbfSopenharmony_ci    audioDeviceDescriptorArray->descriptors = nullptr;
21246f34cbfSopenharmony_ci    free(audioDeviceDescriptorArray);
21346f34cbfSopenharmony_ci    audioDeviceDescriptorArray = nullptr;
21446f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
21546f34cbfSopenharmony_ci}
21646f34cbfSopenharmony_ci
21746f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_IsMicBlockDetectionSupported(
21846f34cbfSopenharmony_ci    OH_AudioRoutingManager *audioRoutingManager, bool *supported)
21946f34cbfSopenharmony_ci{
22046f34cbfSopenharmony_ci    *supported = OHOS::system::GetBoolParameter("const.multimedia.audio.mic_block_detection", false);
22146f34cbfSopenharmony_ci    if (*supported == true) {
22246f34cbfSopenharmony_ci        AUDIO_INFO_LOG("mic block detection supported");
22346f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_SUCCESS;
22446f34cbfSopenharmony_ci    } else {
22546f34cbfSopenharmony_ci        AUDIO_ERR_LOG("mic block detection is not supported");
22646f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
22746f34cbfSopenharmony_ci    }
22846f34cbfSopenharmony_ci}
22946f34cbfSopenharmony_ci
23046f34cbfSopenharmony_ciOH_AudioCommon_Result OH_AudioRoutingManager_SetMicBlockStatusCallback(
23146f34cbfSopenharmony_ci    OH_AudioRoutingManager *audioRoutingManager,
23246f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback, void *userData)
23346f34cbfSopenharmony_ci{
23446f34cbfSopenharmony_ci    OHAudioRoutingManager *ohAudioRoutingManager = convertManager(audioRoutingManager);
23546f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ohAudioRoutingManager != nullptr,
23646f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioRoutingManager is nullptr");
23746f34cbfSopenharmony_ci    ohAudioRoutingManager->SetMicrophoneBlockedCallback(callback, userData);
23846f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
23946f34cbfSopenharmony_ci}
24046f34cbfSopenharmony_ci
24146f34cbfSopenharmony_cinamespace OHOS {
24246f34cbfSopenharmony_cinamespace AudioStandard {
24346f34cbfSopenharmony_ci
24446f34cbfSopenharmony_civoid DestroyAudioDeviceDescriptor(OH_AudioDeviceDescriptorArray *array)
24546f34cbfSopenharmony_ci{
24646f34cbfSopenharmony_ci    if (array) {
24746f34cbfSopenharmony_ci        for (uint32_t index = 0; index < array->size; index++) {
24846f34cbfSopenharmony_ci            OHAudioDeviceDescriptor* ohAudioDeviceDescriptor = (OHAudioDeviceDescriptor*)array->descriptors[index];
24946f34cbfSopenharmony_ci            delete ohAudioDeviceDescriptor;
25046f34cbfSopenharmony_ci            array->descriptors[index] = nullptr;
25146f34cbfSopenharmony_ci        }
25246f34cbfSopenharmony_ci        free(array->descriptors);
25346f34cbfSopenharmony_ci        free(array);
25446f34cbfSopenharmony_ci    }
25546f34cbfSopenharmony_ci}
25646f34cbfSopenharmony_ci
25746f34cbfSopenharmony_ciOHAudioRoutingManager::OHAudioRoutingManager()
25846f34cbfSopenharmony_ci{
25946f34cbfSopenharmony_ci    AUDIO_INFO_LOG("OHAudioRoutingManager created!");
26046f34cbfSopenharmony_ci}
26146f34cbfSopenharmony_ci
26246f34cbfSopenharmony_ciOHAudioRoutingManager::~OHAudioRoutingManager()
26346f34cbfSopenharmony_ci{
26446f34cbfSopenharmony_ci    AUDIO_INFO_LOG("OHAudioRoutingManager destroyed!");
26546f34cbfSopenharmony_ci}
26646f34cbfSopenharmony_ci
26746f34cbfSopenharmony_ciOH_AudioDeviceDescriptorArray *OHAudioRoutingManager::ConvertDesc(std::vector<sptr<AudioDeviceDescriptor>> &desc)
26846f34cbfSopenharmony_ci{
26946f34cbfSopenharmony_ci    size_t size = desc.size();
27046f34cbfSopenharmony_ci    if (size == 0 || size >= MAX_VALID_SIZE) {
27146f34cbfSopenharmony_ci        AUDIO_ERR_LOG("failed to convert device info, size is %{public}zu", size);
27246f34cbfSopenharmony_ci        return nullptr;
27346f34cbfSopenharmony_ci    }
27446f34cbfSopenharmony_ci
27546f34cbfSopenharmony_ci    OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
27646f34cbfSopenharmony_ci        (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
27746f34cbfSopenharmony_ci
27846f34cbfSopenharmony_ci    if (audioDeviceDescriptorArray == nullptr) {
27946f34cbfSopenharmony_ci        AUDIO_ERR_LOG("failed to malloc.");
28046f34cbfSopenharmony_ci        return nullptr;
28146f34cbfSopenharmony_ci    }
28246f34cbfSopenharmony_ci    audioDeviceDescriptorArray->size = 0;
28346f34cbfSopenharmony_ci    audioDeviceDescriptorArray->descriptors =
28446f34cbfSopenharmony_ci        (OH_AudioDeviceDescriptor **)malloc(sizeof(OH_AudioDeviceDescriptor *) * size);
28546f34cbfSopenharmony_ci    if (audioDeviceDescriptorArray->descriptors == nullptr) {
28646f34cbfSopenharmony_ci        free(audioDeviceDescriptorArray);
28746f34cbfSopenharmony_ci        audioDeviceDescriptorArray = nullptr;
28846f34cbfSopenharmony_ci        AUDIO_ERR_LOG("failed to malloc descriptors.");
28946f34cbfSopenharmony_ci        return nullptr;
29046f34cbfSopenharmony_ci    }
29146f34cbfSopenharmony_ci
29246f34cbfSopenharmony_ci    uint32_t index = 0;
29346f34cbfSopenharmony_ci    for (auto deviceDescriptor : desc) {
29446f34cbfSopenharmony_ci        audioDeviceDescriptorArray->descriptors[index] =
29546f34cbfSopenharmony_ci            (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
29646f34cbfSopenharmony_ci        if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
29746f34cbfSopenharmony_ci            DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
29846f34cbfSopenharmony_ci            return nullptr;
29946f34cbfSopenharmony_ci        }
30046f34cbfSopenharmony_ci        index++;
30146f34cbfSopenharmony_ci        audioDeviceDescriptorArray->size = index;
30246f34cbfSopenharmony_ci    }
30346f34cbfSopenharmony_ci    return audioDeviceDescriptorArray;
30446f34cbfSopenharmony_ci}
30546f34cbfSopenharmony_ci
30646f34cbfSopenharmony_ciOH_AudioDeviceDescriptorArray* OHAudioRoutingManager::GetDevices(DeviceFlag deviceFlag)
30746f34cbfSopenharmony_ci{
30846f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
30946f34cbfSopenharmony_ci        nullptr, "failed, audioSystemManager is null");
31046f34cbfSopenharmony_ci    std::vector<sptr<AudioDeviceDescriptor>> audioDeviceDescriptors = audioSystemManager_->GetDevices(deviceFlag);
31146f34cbfSopenharmony_ci    uint32_t size = audioDeviceDescriptors.size();
31246f34cbfSopenharmony_ci    if (size <= 0) {
31346f34cbfSopenharmony_ci        AUDIO_ERR_LOG("audioDeviceDescriptors is null");
31446f34cbfSopenharmony_ci        return nullptr;
31546f34cbfSopenharmony_ci    }
31646f34cbfSopenharmony_ci    return ConvertDesc(audioDeviceDescriptors);
31746f34cbfSopenharmony_ci}
31846f34cbfSopenharmony_ci
31946f34cbfSopenharmony_ciOH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetAvailableDevices(AudioDeviceUsage deviceUsage)
32046f34cbfSopenharmony_ci{
32146f34cbfSopenharmony_ci    std::vector<std::unique_ptr<AudioDeviceDescriptor>> tempDesc =
32246f34cbfSopenharmony_ci        AudioRoutingManager::GetInstance()->GetAvailableDevices(deviceUsage);
32346f34cbfSopenharmony_ci    if (tempDesc.size() == 0) {
32446f34cbfSopenharmony_ci        AUDIO_ERR_LOG("get no device");
32546f34cbfSopenharmony_ci        return nullptr;
32646f34cbfSopenharmony_ci    }
32746f34cbfSopenharmony_ci    std::vector<sptr<AudioDeviceDescriptor>> altaDesc = {};
32846f34cbfSopenharmony_ci    for (const auto &availableDesc : tempDesc) {
32946f34cbfSopenharmony_ci        sptr<AudioDeviceDescriptor> dec = new(std::nothrow) AudioDeviceDescriptor(*availableDesc);
33046f34cbfSopenharmony_ci        altaDesc.push_back(dec);
33146f34cbfSopenharmony_ci    }
33246f34cbfSopenharmony_ci    return ConvertDesc(altaDesc);
33346f34cbfSopenharmony_ci}
33446f34cbfSopenharmony_ci
33546f34cbfSopenharmony_ciOH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetPreferredOutputDevice(StreamUsage streamUsage)
33646f34cbfSopenharmony_ci{
33746f34cbfSopenharmony_ci    AudioRendererInfo rendererInfo = {};
33846f34cbfSopenharmony_ci    rendererInfo.streamUsage = streamUsage;
33946f34cbfSopenharmony_ci    std::vector<sptr<AudioDeviceDescriptor>> desc = {};
34046f34cbfSopenharmony_ci
34146f34cbfSopenharmony_ci    int32_t ret = AudioRoutingManager::GetInstance()->GetPreferredOutputDeviceForRendererInfo(rendererInfo, desc);
34246f34cbfSopenharmony_ci    if (ret != SUCCESS) {
34346f34cbfSopenharmony_ci        AUDIO_ERR_LOG("call failed!");
34446f34cbfSopenharmony_ci        return nullptr;
34546f34cbfSopenharmony_ci    }
34646f34cbfSopenharmony_ci    return ConvertDesc(desc);
34746f34cbfSopenharmony_ci}
34846f34cbfSopenharmony_ci
34946f34cbfSopenharmony_ciOH_AudioDeviceDescriptorArray *OHAudioRoutingManager::GetPreferredInputDevice(SourceType sourceType)
35046f34cbfSopenharmony_ci{
35146f34cbfSopenharmony_ci    AudioCapturerInfo capturerInfo = {};
35246f34cbfSopenharmony_ci    capturerInfo.sourceType = sourceType;
35346f34cbfSopenharmony_ci    std::vector<sptr<AudioDeviceDescriptor>> desc = {};
35446f34cbfSopenharmony_ci
35546f34cbfSopenharmony_ci    int32_t ret = AudioRoutingManager::GetInstance()->GetPreferredInputDeviceForCapturerInfo(capturerInfo, desc);
35646f34cbfSopenharmony_ci    if (ret != SUCCESS) {
35746f34cbfSopenharmony_ci        AUDIO_ERR_LOG("call failed!");
35846f34cbfSopenharmony_ci        return nullptr;
35946f34cbfSopenharmony_ci    }
36046f34cbfSopenharmony_ci    return ConvertDesc(desc);
36146f34cbfSopenharmony_ci}
36246f34cbfSopenharmony_ci
36346f34cbfSopenharmony_ciOH_AudioCommon_Result OHAudioRoutingManager::SetDeviceChangeCallback(const DeviceFlag deviceFlag,
36446f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceChangedCallback callback)
36546f34cbfSopenharmony_ci{
36646f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
36746f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
36846f34cbfSopenharmony_ci    std::shared_ptr<OHAudioDeviceChangedCallback> ohAudioOnDeviceChangedCallback =
36946f34cbfSopenharmony_ci        std::make_shared<OHAudioDeviceChangedCallback>(callback);
37046f34cbfSopenharmony_ci    if (ohAudioOnDeviceChangedCallback) {
37146f34cbfSopenharmony_ci        audioSystemManager_->SetDeviceChangeCallback(deviceFlag, ohAudioOnDeviceChangedCallback);
37246f34cbfSopenharmony_ci        ohAudioOnDeviceChangedCallbackArray_.push_back(ohAudioOnDeviceChangedCallback);
37346f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_SUCCESS;
37446f34cbfSopenharmony_ci    }
37546f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_ERROR_NO_MEMORY;
37646f34cbfSopenharmony_ci}
37746f34cbfSopenharmony_ci
37846f34cbfSopenharmony_ciOH_AudioCommon_Result OHAudioRoutingManager::UnsetDeviceChangeCallback(DeviceFlag deviceFlag,
37946f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceChangedCallback ohOnDeviceChangedcallback)
38046f34cbfSopenharmony_ci{
38146f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
38246f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
38346f34cbfSopenharmony_ci    auto iter = std::find_if(ohAudioOnDeviceChangedCallbackArray_.begin(), ohAudioOnDeviceChangedCallbackArray_.end(),
38446f34cbfSopenharmony_ci        [&](const std::shared_ptr<OHAudioDeviceChangedCallback> &item) {
38546f34cbfSopenharmony_ci        return item->GetCallback() == ohOnDeviceChangedcallback;
38646f34cbfSopenharmony_ci    });
38746f34cbfSopenharmony_ci    if (iter == ohAudioOnDeviceChangedCallbackArray_.end()) {
38846f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
38946f34cbfSopenharmony_ci    }
39046f34cbfSopenharmony_ci    audioSystemManager_->UnsetDeviceChangeCallback(deviceFlag);
39146f34cbfSopenharmony_ci    ohAudioOnDeviceChangedCallbackArray_.erase(iter);
39246f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
39346f34cbfSopenharmony_ci}
39446f34cbfSopenharmony_ci
39546f34cbfSopenharmony_civoid OHAudioDeviceChangedCallback::OnDeviceChange(const DeviceChangeAction &deviceChangeAction)
39646f34cbfSopenharmony_ci{
39746f34cbfSopenharmony_ci    CHECK_AND_RETURN_LOG(callback_ != nullptr, "failed, pointer to the fuction is nullptr");
39846f34cbfSopenharmony_ci    OH_AudioDevice_ChangeType type = static_cast<OH_AudioDevice_ChangeType>(deviceChangeAction.type);
39946f34cbfSopenharmony_ci    uint32_t size = deviceChangeAction.deviceDescriptors.size();
40046f34cbfSopenharmony_ci    if (size <= 0) {
40146f34cbfSopenharmony_ci        AUDIO_ERR_LOG("audioDeviceDescriptors is null");
40246f34cbfSopenharmony_ci        return;
40346f34cbfSopenharmony_ci    }
40446f34cbfSopenharmony_ci
40546f34cbfSopenharmony_ci    OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
40646f34cbfSopenharmony_ci        (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
40746f34cbfSopenharmony_ci    if (audioDeviceDescriptorArray) {
40846f34cbfSopenharmony_ci        audioDeviceDescriptorArray->descriptors =
40946f34cbfSopenharmony_ci            (OH_AudioDeviceDescriptor**)malloc(sizeof(OH_AudioDeviceDescriptor*) * size);
41046f34cbfSopenharmony_ci        if (audioDeviceDescriptorArray->descriptors == nullptr) {
41146f34cbfSopenharmony_ci            free(audioDeviceDescriptorArray);
41246f34cbfSopenharmony_ci            audioDeviceDescriptorArray = nullptr;
41346f34cbfSopenharmony_ci            AUDIO_ERR_LOG("failed to malloc descriptors.");
41446f34cbfSopenharmony_ci            return;
41546f34cbfSopenharmony_ci        }
41646f34cbfSopenharmony_ci        audioDeviceDescriptorArray->size = size;
41746f34cbfSopenharmony_ci        uint32_t index = 0;
41846f34cbfSopenharmony_ci        for (auto deviceDescriptor : deviceChangeAction.deviceDescriptors) {
41946f34cbfSopenharmony_ci            audioDeviceDescriptorArray->descriptors[index] =
42046f34cbfSopenharmony_ci                (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
42146f34cbfSopenharmony_ci            if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
42246f34cbfSopenharmony_ci                DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
42346f34cbfSopenharmony_ci                return;
42446f34cbfSopenharmony_ci            }
42546f34cbfSopenharmony_ci            index++;
42646f34cbfSopenharmony_ci        }
42746f34cbfSopenharmony_ci    }
42846f34cbfSopenharmony_ci    callback_(type, audioDeviceDescriptorArray);
42946f34cbfSopenharmony_ci}
43046f34cbfSopenharmony_ci
43146f34cbfSopenharmony_civoid OHMicrophoneBlockCallback::OnMicrophoneBlocked(const MicrophoneBlockedInfo &microphoneBlockedInfo)
43246f34cbfSopenharmony_ci{
43346f34cbfSopenharmony_ci    AUDIO_INFO_LOG("Enter blocked info: %{public}d", microphoneBlockedInfo.blockStatus);
43446f34cbfSopenharmony_ci    CHECK_AND_RETURN_LOG(blockedCallback_ != nullptr, "failed, pointer to the fuction is nullptr");
43546f34cbfSopenharmony_ci    uint32_t size = microphoneBlockedInfo.devices.size();
43646f34cbfSopenharmony_ci    if (size <= 0) {
43746f34cbfSopenharmony_ci        AUDIO_ERR_LOG("audioDeviceDescriptors is null");
43846f34cbfSopenharmony_ci        return;
43946f34cbfSopenharmony_ci    }
44046f34cbfSopenharmony_ci    OH_AudioDevice_BlockStatus status = static_cast<OH_AudioDevice_BlockStatus>(microphoneBlockedInfo.blockStatus);
44146f34cbfSopenharmony_ci    OH_AudioDeviceDescriptorArray *audioDeviceDescriptorArray =
44246f34cbfSopenharmony_ci        (OH_AudioDeviceDescriptorArray *)malloc(sizeof(OH_AudioDeviceDescriptorArray));
44346f34cbfSopenharmony_ci    if (audioDeviceDescriptorArray) {
44446f34cbfSopenharmony_ci        audioDeviceDescriptorArray->descriptors =
44546f34cbfSopenharmony_ci            (OH_AudioDeviceDescriptor**)malloc(sizeof(OH_AudioDeviceDescriptor*) * size);
44646f34cbfSopenharmony_ci        if (audioDeviceDescriptorArray->descriptors == nullptr) {
44746f34cbfSopenharmony_ci            free(audioDeviceDescriptorArray);
44846f34cbfSopenharmony_ci            audioDeviceDescriptorArray = nullptr;
44946f34cbfSopenharmony_ci            AUDIO_ERR_LOG("failed to malloc descriptors.");
45046f34cbfSopenharmony_ci            return;
45146f34cbfSopenharmony_ci        }
45246f34cbfSopenharmony_ci        audioDeviceDescriptorArray->size = size;
45346f34cbfSopenharmony_ci        uint32_t index = 0;
45446f34cbfSopenharmony_ci        for (auto deviceDescriptor : microphoneBlockedInfo.devices) {
45546f34cbfSopenharmony_ci            audioDeviceDescriptorArray->descriptors[index] =
45646f34cbfSopenharmony_ci                (OH_AudioDeviceDescriptor *)(new OHAudioDeviceDescriptor(deviceDescriptor));
45746f34cbfSopenharmony_ci            if (audioDeviceDescriptorArray->descriptors[index] == nullptr) {
45846f34cbfSopenharmony_ci                DestroyAudioDeviceDescriptor(audioDeviceDescriptorArray);
45946f34cbfSopenharmony_ci                return;
46046f34cbfSopenharmony_ci            }
46146f34cbfSopenharmony_ci            index++;
46246f34cbfSopenharmony_ci        }
46346f34cbfSopenharmony_ci    }
46446f34cbfSopenharmony_ci    blockedCallback_(audioDeviceDescriptorArray, status, nullptr);
46546f34cbfSopenharmony_ci}
46646f34cbfSopenharmony_ci
46746f34cbfSopenharmony_ciOH_AudioCommon_Result OHAudioRoutingManager::SetMicrophoneBlockedCallback(
46846f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback, void *userData)
46946f34cbfSopenharmony_ci{
47046f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
47146f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
47246f34cbfSopenharmony_ci    if (callback == nullptr) {
47346f34cbfSopenharmony_ci        UnsetMicrophoneBlockedCallback(callback);
47446f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_SUCCESS;
47546f34cbfSopenharmony_ci    }
47646f34cbfSopenharmony_ci    std::shared_ptr<OHMicrophoneBlockCallback> microphoneBlock =
47746f34cbfSopenharmony_ci        std::make_shared<OHMicrophoneBlockCallback>(callback, userData);
47846f34cbfSopenharmony_ci    audioSystemManager_->SetMicrophoneBlockedCallback(microphoneBlock);
47946f34cbfSopenharmony_ci    ohMicroPhoneBlockCallbackArray_.push_back(microphoneBlock);
48046f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
48146f34cbfSopenharmony_ci}
48246f34cbfSopenharmony_ci
48346f34cbfSopenharmony_ciOH_AudioCommon_Result OHAudioRoutingManager::UnsetMicrophoneBlockedCallback(
48446f34cbfSopenharmony_ci    OH_AudioRoutingManager_OnDeviceBlockStatusCallback callback)
48546f34cbfSopenharmony_ci{
48646f34cbfSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr,
48746f34cbfSopenharmony_ci        AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "failed, audioSystemManager is null");
48846f34cbfSopenharmony_ci
48946f34cbfSopenharmony_ci    audioSystemManager_->UnsetMicrophoneBlockedCallback();
49046f34cbfSopenharmony_ci
49146f34cbfSopenharmony_ci    auto iter = std::find_if(ohMicroPhoneBlockCallbackArray_.begin(), ohMicroPhoneBlockCallbackArray_.end(),
49246f34cbfSopenharmony_ci        [&](const std::shared_ptr<OHMicrophoneBlockCallback> &item) {
49346f34cbfSopenharmony_ci        return item->GetCallback() == callback;
49446f34cbfSopenharmony_ci    });
49546f34cbfSopenharmony_ci    if (iter == ohMicroPhoneBlockCallbackArray_.end()) {
49646f34cbfSopenharmony_ci        return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
49746f34cbfSopenharmony_ci    }
49846f34cbfSopenharmony_ci
49946f34cbfSopenharmony_ci    ohMicroPhoneBlockCallbackArray_.erase(iter);
50046f34cbfSopenharmony_ci    return AUDIOCOMMON_RESULT_SUCCESS;
50146f34cbfSopenharmony_ci}
50246f34cbfSopenharmony_ci}  // namespace AudioStandard
50346f34cbfSopenharmony_ci}  // namespace OHOS