1 /*
2 * Copyright (c) 2022 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 "audio_system_manager_adapter_impl.h"
17
18 #include <unordered_map>
19
20 #include "audio_errors.h"
21 #include "audio_renderer_adapter_impl.h"
22 #include "nweb_log.h"
23
24 namespace OHOS::NWeb {
25 const std::unordered_map<AudioAdapterStreamType, AudioStreamType> STREAM_TYPE_MAP = {
26 { AudioAdapterStreamType::STREAM_DEFAULT, AudioStreamType::STREAM_DEFAULT },
27 { AudioAdapterStreamType::STREAM_VOICE_CALL, AudioStreamType::STREAM_VOICE_CALL },
28 { AudioAdapterStreamType::STREAM_MUSIC, AudioStreamType::STREAM_MUSIC },
29 { AudioAdapterStreamType::STREAM_RING, AudioStreamType::STREAM_RING },
30 { AudioAdapterStreamType::STREAM_MEDIA, AudioStreamType::STREAM_MEDIA },
31 { AudioAdapterStreamType::STREAM_VOICE_ASSISTANT, AudioStreamType::STREAM_VOICE_ASSISTANT },
32 { AudioAdapterStreamType::STREAM_SYSTEM, AudioStreamType::STREAM_SYSTEM },
33 { AudioAdapterStreamType::STREAM_ALARM, AudioStreamType::STREAM_ALARM },
34 { AudioAdapterStreamType::STREAM_NOTIFICATION, AudioStreamType::STREAM_NOTIFICATION },
35 { AudioAdapterStreamType::STREAM_BLUETOOTH_SCO, AudioStreamType::STREAM_BLUETOOTH_SCO },
36 { AudioAdapterStreamType::STREAM_ENFORCED_AUDIBLE, AudioStreamType::STREAM_ENFORCED_AUDIBLE },
37 { AudioAdapterStreamType::STREAM_DTMF, AudioStreamType::STREAM_DTMF },
38 { AudioAdapterStreamType::STREAM_TTS, AudioStreamType::STREAM_TTS },
39 { AudioAdapterStreamType::STREAM_ACCESSIBILITY, AudioStreamType::STREAM_ACCESSIBILITY },
40 { AudioAdapterStreamType::STREAM_RECORDING, AudioStreamType::STREAM_RECORDING },
41 { AudioAdapterStreamType::STREAM_ALL, AudioStreamType::STREAM_ALL },
42 };
43
44 const std::unordered_map<AdapterDeviceFlag, DeviceFlag> DEVICE_FLAG_MAP = {
45 { AdapterDeviceFlag::NONE_DEVICES_FLAG, DeviceFlag::NONE_DEVICES_FLAG },
46 { AdapterDeviceFlag::OUTPUT_DEVICES_FLAG, DeviceFlag::OUTPUT_DEVICES_FLAG },
47 { AdapterDeviceFlag::INPUT_DEVICES_FLAG, DeviceFlag::INPUT_DEVICES_FLAG },
48 { AdapterDeviceFlag::ALL_DEVICES_FLAG, DeviceFlag::ALL_DEVICES_FLAG },
49 { AdapterDeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG, DeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG },
50 { AdapterDeviceFlag::DISTRIBUTED_INPUT_DEVICES_FLAG, DeviceFlag::DISTRIBUTED_INPUT_DEVICES_FLAG },
51 { AdapterDeviceFlag::ALL_DISTRIBUTED_DEVICES_FLAG, DeviceFlag::ALL_DISTRIBUTED_DEVICES_FLAG },
52 { AdapterDeviceFlag::ALL_L_D_DEVICES_FLAG, DeviceFlag::ALL_L_D_DEVICES_FLAG },
53 { AdapterDeviceFlag::DEVICE_FLAG_MAX, DeviceFlag::DEVICE_FLAG_MAX },
54 };
55
56 const std::string DEVICE_TYPE_NONE = "device/none";
57 const std::string DEVICE_TYPE_INVALID = "device/invalid";
58 const std::string DEVICE_TYPE_EARPIECE = "device/earpiece";
59 const std::string DEVICE_TYPE_SPEAKER = "device/speaker";
60 const std::string DEVICE_TYPE_WIRED_HEADSET = "device/wired_headset";
61 const std::string DEVICE_TYPE_WIRED_HEADPHONES = "device/wired_headphones";
62 const std::string DEVICE_TYPE_BLUETOOTH_SCO = "device/bluetooth_sco";
63 const std::string DEVICE_TYPE_BLUETOOTH_A2DP = "device/bluetooth_a2dp";
64 const std::string DEVICE_TYPE_MIC = "device/mic";
65 const std::string DEVICE_TYPE_USB_HEADSET = "device/usb_headset";
66 const std::string DEVICE_TYPE_FILE_SINK = "device/file_sink";
67 const std::string DEVICE_TYPE_FILE_SOURCE = "device/file_source";
68 const std::string DEVICE_TYPE_MAX = "device/max";
69
70 const std::unordered_map<DeviceType, std::string> DEVICE_TYPE_MAP = {
71 { DeviceType::DEVICE_TYPE_NONE, DEVICE_TYPE_NONE },
72 { DeviceType::DEVICE_TYPE_INVALID, DEVICE_TYPE_INVALID },
73 { DeviceType::DEVICE_TYPE_EARPIECE, DEVICE_TYPE_EARPIECE },
74 { DeviceType::DEVICE_TYPE_SPEAKER, DEVICE_TYPE_SPEAKER },
75 { DeviceType::DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_WIRED_HEADSET },
76 { DeviceType::DEVICE_TYPE_WIRED_HEADPHONES, DEVICE_TYPE_WIRED_HEADPHONES },
77 { DeviceType::DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_BLUETOOTH_SCO },
78 { DeviceType::DEVICE_TYPE_BLUETOOTH_A2DP, DEVICE_TYPE_BLUETOOTH_A2DP },
79 { DeviceType::DEVICE_TYPE_MIC, DEVICE_TYPE_MIC },
80 { DeviceType::DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_USB_HEADSET },
81 { DeviceType::DEVICE_TYPE_FILE_SINK, DEVICE_TYPE_FILE_SINK },
82 { DeviceType::DEVICE_TYPE_FILE_SOURCE, DEVICE_TYPE_FILE_SOURCE },
83 { DeviceType::DEVICE_TYPE_MAX, DEVICE_TYPE_MAX },
84 };
85
86 const int32_t ADAPTER_AUDIO_DEFAULT_DEVICE_ID = 1000000;
87 const char* ADAPTER_AUDIO_DEFAULT_DEVICE_NAME = "(default)";
88
AudioManagerCallbackAdapterImpl(std::shared_ptr<AudioManagerCallbackAdapter> cb)89 AudioManagerCallbackAdapterImpl::AudioManagerCallbackAdapterImpl(std::shared_ptr<AudioManagerCallbackAdapter> cb)
90 : cb_(cb) {};
91
OnInterrupt(const InterruptAction & interruptAction)92 void AudioManagerCallbackAdapterImpl::OnInterrupt(const InterruptAction& interruptAction)
93 {
94 if (!cb_) {
95 return;
96 }
97 switch (interruptAction.interruptHint) {
98 case InterruptHint::INTERRUPT_HINT_PAUSE:
99 case InterruptHint::INTERRUPT_HINT_STOP:
100 cb_->OnSuspend();
101 break;
102 case InterruptHint::INTERRUPT_HINT_RESUME:
103 cb_->OnResume();
104 break;
105 default:
106 WVLOG_E("audio manager interrupt hint not foud, code: %{public}d", interruptAction.interruptHint);
107 break;
108 }
109 }
110
AudioManagerDeviceChangeCallbackAdapterImpl(std::shared_ptr<AudioManagerDeviceChangeCallbackAdapter> cb)111 AudioManagerDeviceChangeCallbackAdapterImpl::AudioManagerDeviceChangeCallbackAdapterImpl(
112 std::shared_ptr<AudioManagerDeviceChangeCallbackAdapter> cb)
113 : cb_(cb) {};
114
OnDeviceChange(const DeviceChangeAction & deviceChangeAction)115 void AudioManagerDeviceChangeCallbackAdapterImpl::OnDeviceChange(const DeviceChangeAction& deviceChangeAction)
116 {
117 if (!cb_) {
118 return;
119 }
120 cb_->OnDeviceChange();
121 }
122
GetInstance()123 AudioSystemManagerAdapterImpl& AudioSystemManagerAdapterImpl::GetInstance()
124 {
125 static AudioSystemManagerAdapterImpl instance;
126 return instance;
127 }
128
HasAudioOutputDevices() const129 bool AudioSystemManagerAdapterImpl::HasAudioOutputDevices() const
130 {
131 DeviceType outputDeviceType = AudioSystemManager::GetInstance()->GetActiveOutputDevice();
132 if (outputDeviceType == DeviceType::DEVICE_TYPE_NONE || outputDeviceType == DeviceType::DEVICE_TYPE_INVALID) {
133 return false;
134 }
135 return true;
136 }
137
HasAudioInputDevices() const138 bool AudioSystemManagerAdapterImpl::HasAudioInputDevices() const
139 {
140 DeviceType inputDeviceType = AudioSystemManager::GetInstance()->GetActiveInputDevice();
141 if (inputDeviceType == DeviceType::DEVICE_TYPE_NONE || inputDeviceType == DeviceType::DEVICE_TYPE_INVALID) {
142 return false;
143 }
144 return true;
145 }
146
RequestAudioFocus(const AudioAdapterInterrupt & audioInterrupt)147 int32_t AudioSystemManagerAdapterImpl::RequestAudioFocus(const AudioAdapterInterrupt& audioInterrupt)
148 {
149 AudioInterrupt interruptParams;
150 interruptParams.streamUsage = AudioRendererAdapterImpl::GetAudioStreamUsage(audioInterrupt.streamUsage);
151 interruptParams.contentType = AudioRendererAdapterImpl::GetAudioContentType(audioInterrupt.contentType);
152 interruptParams.audioFocusType.streamType = GetStreamType(audioInterrupt.streamType);
153
154 int32_t ret = AudioSystemManager::GetInstance()->RequestAudioFocus(interruptParams);
155 if (ret != AudioStandard::SUCCESS) {
156 WVLOG_E("audio request audio focus failed, code: %{public}d", ret);
157 return AUDIO_ERROR;
158 }
159 return AUDIO_OK;
160 }
161
AbandonAudioFocus(const AudioAdapterInterrupt & audioInterrupt)162 int32_t AudioSystemManagerAdapterImpl::AbandonAudioFocus(const AudioAdapterInterrupt& audioInterrupt)
163 {
164 AudioInterrupt interruptParams;
165 interruptParams.streamUsage = AudioRendererAdapterImpl::GetAudioStreamUsage(audioInterrupt.streamUsage);
166 interruptParams.contentType = AudioRendererAdapterImpl::GetAudioContentType(audioInterrupt.contentType);
167 interruptParams.audioFocusType.streamType = GetStreamType(audioInterrupt.streamType);
168
169 int32_t ret = AudioSystemManager::GetInstance()->AbandonAudioFocus(interruptParams);
170 if (ret != AudioStandard::SUCCESS) {
171 WVLOG_E("audio abandon audio focus failed, code: %{public}d", ret);
172 return AUDIO_ERROR;
173 }
174 return AUDIO_OK;
175 }
176
SetAudioManagerInterruptCallback(const std::shared_ptr<AudioManagerCallbackAdapter> & callback)177 int32_t AudioSystemManagerAdapterImpl::SetAudioManagerInterruptCallback(
178 const std::shared_ptr<AudioManagerCallbackAdapter>& callback)
179 {
180 if (callback == nullptr) {
181 WVLOG_E("set audio manager interrupt callback is nullptr");
182 return AUDIO_NULL_ERROR;
183 }
184 callback_ = std::make_shared<AudioManagerCallbackAdapterImpl>(callback);
185
186 int32_t ret = AudioSystemManager::GetInstance()->SetAudioManagerInterruptCallback(callback_);
187 if (ret != AudioStandard::SUCCESS) {
188 WVLOG_E("audio manager set interrupt callback failed, code: %{public}d", ret);
189 return AUDIO_ERROR;
190 }
191 return AUDIO_OK;
192 }
193
UnsetAudioManagerInterruptCallback()194 int32_t AudioSystemManagerAdapterImpl::UnsetAudioManagerInterruptCallback()
195 {
196 int32_t ret = AudioSystemManager::GetInstance()->UnsetAudioManagerInterruptCallback();
197 if (ret != AudioStandard::SUCCESS) {
198 WVLOG_E("audio manager unset interrupt callback failed, code: %{public}d", ret);
199 return AUDIO_ERROR;
200 }
201 callback_ = nullptr;
202 return AUDIO_OK;
203 }
204
GetDevices(AdapterDeviceFlag flag) const205 std::vector<AudioAdapterDeviceDesc> AudioSystemManagerAdapterImpl::GetDevices(AdapterDeviceFlag flag) const
206 {
207 auto item = DEVICE_FLAG_MAP.find(flag);
208 if (item == DEVICE_FLAG_MAP.end()) {
209 WVLOG_E("audio device type not found");
210 return std::vector<AudioAdapterDeviceDesc>();
211 }
212 auto deviceFlag = item->second;
213 auto audioDeviceList = AudioSystemManager::GetInstance()->GetDevices(deviceFlag);
214 std::vector<AudioAdapterDeviceDesc> audioAdapterDeviceList;
215 for (auto audioDevice : audioDeviceList) {
216 AudioAdapterDeviceDesc desc;
217 desc.deviceId = audioDevice->deviceId_;
218 auto deviceTypeKey = DEVICE_TYPE_MAP.find(audioDevice->deviceType_);
219 if (deviceTypeKey != DEVICE_TYPE_MAP.end()) {
220 desc.deviceName = deviceTypeKey->second;
221 }
222 audioAdapterDeviceList.emplace_back(desc);
223 }
224 return audioAdapterDeviceList;
225 }
226
SelectAudioDevice(AudioAdapterDeviceDesc desc,bool isInput) const227 int32_t AudioSystemManagerAdapterImpl::SelectAudioDevice(AudioAdapterDeviceDesc desc, bool isInput) const
228 {
229 WVLOG_I("AudioSystemManagerAdapterImpl::SelectAudioDevice isInput: %{public}s", isInput ? "true" : "false");
230 auto item = isInput ? DEVICE_FLAG_MAP.find(AdapterDeviceFlag::INPUT_DEVICES_FLAG)
231 : DEVICE_FLAG_MAP.find(AdapterDeviceFlag::OUTPUT_DEVICES_FLAG);
232 if (item == DEVICE_FLAG_MAP.end()) {
233 WVLOG_E("audio device type not found");
234 return AUDIO_ERROR;
235 }
236 auto deviceFlag = item->second;
237 if (!isInput && desc.deviceId == ADAPTER_AUDIO_DEFAULT_DEVICE_ID) {
238 WVLOG_I("Select default audio output Device.");
239 AudioRendererInfo rendererInfo;
240 rendererInfo.contentType = ContentType::CONTENT_TYPE_SPEECH;
241 rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
242 rendererInfo.rendererFlags = 0;
243 std::vector<sptr<AudioDeviceDescriptor>> defaultOutputDevice;
244 AudioRoutingManager::GetInstance()->GetPreferredOutputDeviceForRendererInfo(rendererInfo, defaultOutputDevice);
245 AudioSystemManager::GetInstance()->SelectInputDevice(defaultOutputDevice);
246 return AUDIO_OK;
247 }
248 auto audioDeviceList = AudioSystemManager::GetInstance()->GetDevices(deviceFlag);
249 for (auto device : audioDeviceList) {
250 if (device->deviceId_ == desc.deviceId) {
251 std::vector<sptr<AudioDeviceDescriptor>> selectedAudioDevice { device };
252 return isInput ? AudioSystemManager::GetInstance()->SelectInputDevice(selectedAudioDevice)
253 : AudioSystemManager::GetInstance()->SelectOutputDevice(selectedAudioDevice);
254 }
255 }
256 WVLOG_E("can't find any device by audio device id");
257 return AUDIO_ERROR;
258 }
259
GetDefaultOutputDevice()260 AudioAdapterDeviceDesc AudioSystemManagerAdapterImpl::GetDefaultOutputDevice()
261 {
262 AudioRendererInfo rendererInfo;
263 rendererInfo.contentType = ContentType::CONTENT_TYPE_SPEECH;
264 rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
265 rendererInfo.rendererFlags = 0;
266 std::vector<sptr<AudioDeviceDescriptor>> defaultOutputDevice;
267 AudioRoutingManager::GetInstance()->GetPreferredOutputDeviceForRendererInfo(rendererInfo, defaultOutputDevice);
268
269 AudioAdapterDeviceDesc desc;
270 auto deviceTypeKey = DEVICE_TYPE_MAP.find(defaultOutputDevice[0]->deviceType_);
271 desc.deviceId = defaultOutputDevice[0]->deviceId_;
272 if (deviceTypeKey != DEVICE_TYPE_MAP.end()) {
273 desc.deviceName = deviceTypeKey->second;
274 }
275 return desc;
276 }
277
SetDeviceChangeCallback(const std::shared_ptr<AudioManagerDeviceChangeCallbackAdapter> & callback)278 int32_t AudioSystemManagerAdapterImpl::SetDeviceChangeCallback(
279 const std::shared_ptr<AudioManagerDeviceChangeCallbackAdapter>& callback)
280 {
281 if (callback == nullptr) {
282 WVLOG_E("audio device change callback is nullptr");
283 return AUDIO_NULL_ERROR;
284 }
285 DeviceFlag deviceFlag = DeviceFlag::OUTPUT_DEVICES_FLAG;
286 deviceChangeCallback_ = std::make_shared<AudioManagerDeviceChangeCallbackAdapterImpl>(callback);
287 if (deviceChangeCallback_ == nullptr) {
288 WVLOG_E("audio device change callback impl is nullptr");
289 return AUDIO_NULL_ERROR;
290 }
291 int32_t ret = AudioSystemManager::GetInstance()->SetDeviceChangeCallback(deviceFlag, deviceChangeCallback_);
292 if (ret != AudioStandard::SUCCESS) {
293 WVLOG_E("audio manager set audio device change callback failed, code: %{public}d", ret);
294 return AUDIO_ERROR;
295 }
296 return AUDIO_OK;
297 }
298
UnsetDeviceChangeCallback()299 int32_t AudioSystemManagerAdapterImpl::UnsetDeviceChangeCallback()
300 {
301 int32_t ret = AudioSystemManager::GetInstance()->UnsetDeviceChangeCallback();
302 return ret;
303 }
304
GetStreamType(AudioAdapterStreamType streamType)305 AudioStreamType AudioSystemManagerAdapterImpl::GetStreamType(AudioAdapterStreamType streamType)
306 {
307 auto item = STREAM_TYPE_MAP.find(streamType);
308 if (item == STREAM_TYPE_MAP.end()) {
309 WVLOG_E("audio stream type not found");
310 return AudioStreamType::STREAM_DEFAULT;
311 }
312 return item->second;
313 }
314 } // namespace OHOS::NWeb