1 /*
2 * Copyright (c) 2024-2025 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 #include "multimedia_audio_routing_manager_impl.h"
16 #include "cj_lambda.h"
17 #include "audio_policy_log.h"
18 #include "multimedia_audio_common.h"
19 #include "multimedia_audio_error.h"
20
21 namespace OHOS {
22 namespace AudioStandard {
23 extern "C" {
MMAAudioRoutingManagerImpl()24 MMAAudioRoutingManagerImpl::MMAAudioRoutingManagerImpl()
25 {
26 routingMgr_ = AudioRoutingManager::GetInstance();
27 audioMgr_ = AudioSystemManager::GetInstance();
28 deviceUsageCallback_ = std::make_shared<CjAudioManagerAvailableDeviceChangeCallback>();
29 preferredInputDeviceChangeCallBack_ = std::make_shared<CjAudioPreferredInputDeviceChangeCallback>();
30 preferredOutputDeviceChangeCallBack_ = std::make_shared<CjAudioPreferredOutputDeviceChangeCallback>();
31 deviceChangeCallBack_ = std::make_shared<CjAudioManagerDeviceChangeCallback>();
32 }
33
~MMAAudioRoutingManagerImpl()34 MMAAudioRoutingManagerImpl::~MMAAudioRoutingManagerImpl()
35 {
36 routingMgr_ = nullptr;
37 audioMgr_ = nullptr;
38 }
39
IsCommunicationDeviceActive(int32_t deviceType)40 bool MMAAudioRoutingManagerImpl::IsCommunicationDeviceActive(int32_t deviceType)
41 {
42 return audioMgr_->IsDeviceActive(static_cast<DeviceType>(deviceType));
43 }
44
SetCommunicationDevice(int32_t deviceType,bool active)45 int32_t MMAAudioRoutingManagerImpl::SetCommunicationDevice(int32_t deviceType, bool active)
46 {
47 auto ret = audioMgr_->SetDeviceActive(static_cast<DeviceType>(deviceType), active);
48 if (ret != SUCCESS_CODE) {
49 AUDIO_ERR_LOG("set communication device failure!");
50 return CJ_ERR_SYSTEM;
51 }
52 return SUCCESS_CODE;
53 }
54
GetDevices(int32_t flags,int32_t * errorCode)55 CArrDeviceDescriptor MMAAudioRoutingManagerImpl::GetDevices(int32_t flags, int32_t *errorCode)
56 {
57 std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceDescriptors =
58 audioMgr_->GetDevices(static_cast<DeviceFlag>(flags));
59 if (deviceDescriptors.empty()) {
60 *errorCode = CJ_ERR_SYSTEM;
61 return CArrDeviceDescriptor();
62 }
63 CArrDeviceDescriptor arr{};
64 Convert2CArrDeviceDescriptor(arr, deviceDescriptors, errorCode);
65 if (*errorCode != SUCCESS_CODE) {
66 FreeCArrDeviceDescriptor(arr);
67 return CArrDeviceDescriptor();
68 }
69 return arr;
70 }
71
GetPreferredInputDeviceForCapturerInfo(CAudioCapturerInfo cInfo,int32_t * errorCode)72 CArrDeviceDescriptor MMAAudioRoutingManagerImpl::GetPreferredInputDeviceForCapturerInfo(CAudioCapturerInfo cInfo,
73 int32_t *errorCode)
74 {
75 std::vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors{};
76 AudioCapturerInfo capturerInfo(static_cast<SourceType>(cInfo.source), cInfo.capturerFlags);
77 routingMgr_->GetPreferredInputDeviceForCapturerInfo(capturerInfo, outDeviceDescriptors);
78 if (outDeviceDescriptors.empty()) {
79 *errorCode = CJ_ERR_SYSTEM;
80 return CArrDeviceDescriptor();
81 }
82 CArrDeviceDescriptor arr{};
83 Convert2CArrDeviceDescriptor(arr, outDeviceDescriptors, errorCode);
84 if (*errorCode != SUCCESS_CODE) {
85 FreeCArrDeviceDescriptor(arr);
86 return CArrDeviceDescriptor();
87 }
88 return arr;
89 }
90
GetPreferredOutputDeviceForRendererInfo(CAudioRendererInfo cInfo,int32_t * errorCode)91 CArrDeviceDescriptor MMAAudioRoutingManagerImpl::GetPreferredOutputDeviceForRendererInfo(CAudioRendererInfo cInfo,
92 int32_t *errorCode)
93 {
94 std::vector<std::shared_ptr<AudioDeviceDescriptor>> outDeviceDescriptors{};
95 AudioRendererInfo rendererInfo{};
96 rendererInfo.streamUsage = static_cast<StreamUsage>(cInfo.usage);
97 rendererInfo.rendererFlags = cInfo.rendererFlags;
98 routingMgr_->GetPreferredOutputDeviceForRendererInfo(rendererInfo, outDeviceDescriptors);
99 if (outDeviceDescriptors.empty()) {
100 *errorCode = CJ_ERR_SYSTEM;
101 return CArrDeviceDescriptor();
102 }
103 CArrDeviceDescriptor arr{};
104 Convert2CArrDeviceDescriptor(arr, outDeviceDescriptors, errorCode);
105 if (*errorCode != SUCCESS_CODE) {
106 FreeCArrDeviceDescriptor(arr);
107 return CArrDeviceDescriptor();
108 }
109 return arr;
110 }
111
RegisterCallback(int32_t callbackType,uint32_t deviceUsage,void (* callback)(),int32_t * errorCode)112 void MMAAudioRoutingManagerImpl::RegisterCallback(int32_t callbackType, uint32_t deviceUsage,
113 void (*callback)(), int32_t *errorCode)
114 {
115 if (callbackType == AudioRoutingManagerCallbackType::AVAILABLE_DEVICE_CHANGE) {
116 auto func = CJLambda::Create(reinterpret_cast<void (*)(CDeviceChangeAction)>(callback));
117 if (func == nullptr) {
118 AUDIO_ERR_LOG("Register avaibleDeviceChange event failure!");
119 *errorCode = CJ_ERR_SYSTEM;
120 return;
121 }
122 deviceUsageCallback_->RegisterFunc(deviceUsage, func);
123 AudioDeviceUsage audioDeviceUsage = static_cast<AudioDeviceUsage>(deviceUsage);
124 audioMgr_->SetAvailableDeviceChangeCallback(audioDeviceUsage, deviceUsageCallback_);
125 }
126 }
127
RegisterPreferredInputDeviceChangeCallback(int32_t callbackType,void (* callback)(),CAudioCapturerInfo info,int32_t * errorCode)128 void MMAAudioRoutingManagerImpl::RegisterPreferredInputDeviceChangeCallback(int32_t callbackType, void (*callback)(),
129 CAudioCapturerInfo info, int32_t *errorCode)
130 {
131 if (callbackType == AudioRoutingManagerCallbackType::INPUT_DEVICE_CHANGE_FOR_CAPTURER_INFO) {
132 auto func = CJLambda::Create(reinterpret_cast<void (*)(CArrDeviceDescriptor)>(callback));
133 if (func == nullptr) {
134 AUDIO_ERR_LOG("Register preferredInputDeviceChangeForCapturerInfo event failure!");
135 *errorCode = CJ_ERR_SYSTEM;
136 return;
137 }
138 AudioCapturerInfo capturerInfo(static_cast<SourceType>(info.source), info.capturerFlags);
139 preferredInputDeviceChangeCallBack_->RegisterFunc(func);
140 routingMgr_->SetPreferredInputDeviceChangeCallback(capturerInfo, preferredInputDeviceChangeCallBack_);
141 }
142 }
143
RegisterPreferredOutputDeviceChangeCallback(int32_t callbackType,void (* callback)(),CAudioRendererInfo info,int32_t * errorCode)144 void MMAAudioRoutingManagerImpl::RegisterPreferredOutputDeviceChangeCallback(int32_t callbackType, void (*callback)(),
145 CAudioRendererInfo info, int32_t *errorCode)
146 {
147 if (callbackType == AudioRoutingManagerCallbackType::OUTPUT_DEVICE_CHANGE_FOR_RENDERER_INFO) {
148 auto func = CJLambda::Create(reinterpret_cast<void (*)(CArrDeviceDescriptor)>(callback));
149 if (func == nullptr) {
150 AUDIO_ERR_LOG("Register preferredOutputDeviceChangeForRendererInfo event failure!");
151 *errorCode = CJ_ERR_SYSTEM;
152 return;
153 }
154 AudioRendererInfo rendererInfo{};
155 rendererInfo.streamUsage = static_cast<StreamUsage>(info.usage);
156 rendererInfo.rendererFlags = info.rendererFlags;
157 preferredOutputDeviceChangeCallBack_->RegisterFunc(func);
158 routingMgr_->SetPreferredOutputDeviceChangeCallback(rendererInfo, preferredOutputDeviceChangeCallBack_);
159 }
160 }
161
RegisterDeviceChangeCallback(int32_t callbackType,void (* callback)(),int32_t flags,int32_t * errorCode)162 void MMAAudioRoutingManagerImpl::RegisterDeviceChangeCallback(int32_t callbackType, void (*callback)(), int32_t flags,
163 int32_t *errorCode)
164 {
165 if (callbackType == AudioRoutingManagerCallbackType::DEVICE_CHANGE) {
166 auto func = CJLambda::Create(reinterpret_cast<void (*)(CDeviceChangeAction)>(callback));
167 if (func == nullptr) {
168 AUDIO_ERR_LOG("Register DeviceChangeAction event failure!");
169 *errorCode = CJ_ERR_SYSTEM;
170 return;
171 }
172 DeviceFlag deviceFlag = static_cast<DeviceFlag>(flags);
173 deviceChangeCallBack_->RegisterFunc(func);
174 audioMgr_->SetDeviceChangeCallback(deviceFlag, deviceChangeCallBack_);
175 }
176 }
177 }
178 } // namespace AudioStandard
179 } // namespace OHOS
180