1 /*
2 * Copyright (C) 2021 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_device_manager.h"
17
18 #include "audio_control_manager.h"
19 #include "bluetooth_call_manager.h"
20 #include "bluetooth_device_state.h"
21 #include "call_ability_report_proxy.h"
22 #include "earpiece_device_state.h"
23 #include "inactive_device_state.h"
24 #include "speaker_device_state.h"
25 #include "telephony_log_wrapper.h"
26 #include "wired_headset_device_state.h"
27
28 namespace OHOS {
29 namespace Telephony {
30 bool AudioDeviceManager::isBtScoDevEnable_ = false;
31 bool AudioDeviceManager::isSpeakerAvailable_ = true; // default available
32 bool AudioDeviceManager::isEarpieceAvailable_ = true;
33 bool AudioDeviceManager::isWiredHeadsetConnected_ = false;
34 bool AudioDeviceManager::isBtScoConnected_ = false;
35
AudioDeviceManager()36 AudioDeviceManager::AudioDeviceManager()
37 : audioDeviceType_(AudioDeviceType::DEVICE_UNKNOWN), currentAudioDevice_(nullptr), isAudioActivated_(false)
38 {}
39
~AudioDeviceManager()40 AudioDeviceManager::~AudioDeviceManager()
41 {
42 memberFuncMap_.clear();
43 }
44
Init()45 void AudioDeviceManager::Init()
46 {
47 memberFuncMap_[AudioEvent::ENABLE_DEVICE_EARPIECE] = &AudioDeviceManager::EnableEarpiece;
48 memberFuncMap_[AudioEvent::ENABLE_DEVICE_SPEAKER] = &AudioDeviceManager::EnableSpeaker;
49 memberFuncMap_[AudioEvent::ENABLE_DEVICE_WIRED_HEADSET] = &AudioDeviceManager::EnableWiredHeadset;
50 memberFuncMap_[AudioEvent::ENABLE_DEVICE_BLUETOOTH] = &AudioDeviceManager::EnableBtSco;
51 currentAudioDevice_ = std::make_unique<InactiveDeviceState>();
52 if (currentAudioDevice_ == nullptr) {
53 TELEPHONY_LOGE("current audio device nullptr");
54 }
55 if (memset_s(&info_, sizeof(AudioDeviceInfo), 0, sizeof(AudioDeviceInfo)) != EOK) {
56 TELEPHONY_LOGE("memset_s address fail");
57 return;
58 }
59 AudioDevice speaker = {
60 .deviceType = AudioDeviceType::DEVICE_SPEAKER,
61 .address = { 0 },
62 };
63 info_.audioDeviceList.push_back(speaker);
64 AudioDevice earpiece = {
65 .deviceType = AudioDeviceType::DEVICE_EARPIECE,
66 .address = { 0 },
67 };
68 info_.audioDeviceList.push_back(earpiece);
69 }
70
AddAudioDeviceList(const std::string & address,AudioDeviceType deviceType)71 void AudioDeviceManager::AddAudioDeviceList(const std::string &address, AudioDeviceType deviceType)
72 {
73 std::lock_guard<std::mutex> lock(infoMutex_);
74 std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
75 while (it != info_.audioDeviceList.end()) {
76 if (it->address == address && it->deviceType == deviceType) {
77 TELEPHONY_LOGI("device is already existenced");
78 return;
79 }
80 if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && it->deviceType == AudioDeviceType::DEVICE_EARPIECE) {
81 it = info_.audioDeviceList.erase(it);
82 TELEPHONY_LOGI("remove Earpiece device success");
83 } else {
84 ++it;
85 }
86 }
87 AudioDevice audioDevice;
88 if (memset_s(&audioDevice, sizeof(AudioDevice), 0, sizeof(AudioDevice)) != EOK) {
89 TELEPHONY_LOGE("memset_s fail");
90 return;
91 }
92 audioDevice.deviceType = deviceType;
93 if (address.length() > kMaxAddressLen) {
94 TELEPHONY_LOGE("address is not too long");
95 return;
96 }
97 if (memcpy_s(audioDevice.address, kMaxAddressLen, address.c_str(), address.length()) != EOK) {
98 TELEPHONY_LOGE("memcpy_s address fail");
99 return;
100 }
101 info_.audioDeviceList.push_back(audioDevice);
102 if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET) {
103 SetDeviceAvailable(AudioDeviceType::DEVICE_WIRED_HEADSET, true);
104 }
105 if (deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
106 SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, true);
107 }
108 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
109 TELEPHONY_LOGI("AddAudioDeviceList success");
110 }
111
RemoveAudioDeviceList(const std::string & address,AudioDeviceType deviceType)112 void AudioDeviceManager::RemoveAudioDeviceList(const std::string &address, AudioDeviceType deviceType)
113 {
114 std::lock_guard<std::mutex> lock(infoMutex_);
115 bool needAddEarpiece = true;
116 std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
117 while (it != info_.audioDeviceList.end()) {
118 if (it->deviceType == AudioDeviceType::DEVICE_EARPIECE) {
119 needAddEarpiece = false;
120 }
121 if (it->address == address && it->deviceType == deviceType) {
122 it = info_.audioDeviceList.erase(it);
123 } else {
124 ++it;
125 }
126 }
127
128 bool wiredHeadsetExist = false;
129 bool blueToothScoExist = false;
130 for (auto &elem : info_.audioDeviceList) {
131 if (elem.deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET) {
132 wiredHeadsetExist = true;
133 }
134 if (elem.deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
135 blueToothScoExist = true;
136 }
137 }
138 if (deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && !wiredHeadsetExist) {
139 SetDeviceAvailable(AudioDeviceType::DEVICE_WIRED_HEADSET, false);
140 }
141 if (deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO && !blueToothScoExist) {
142 SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, false);
143 }
144 if (needAddEarpiece && deviceType == AudioDeviceType::DEVICE_WIRED_HEADSET && !wiredHeadsetExist) {
145 AudioDevice audioDevice = {
146 .deviceType = AudioDeviceType::DEVICE_EARPIECE,
147 .address = { 0 },
148 };
149 info_.audioDeviceList.push_back(audioDevice);
150 TELEPHONY_LOGI("add Earpiece device success");
151 }
152 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
153 TELEPHONY_LOGI("RemoveAudioDeviceList success");
154 }
155
ResetBtAudioDevicesList()156 void AudioDeviceManager::ResetBtAudioDevicesList()
157 {
158 std::lock_guard<std::mutex> lock(mutex_);
159 std::vector<AudioDevice>::iterator it = info_.audioDeviceList.begin();
160 while (it != info_.audioDeviceList.end()) {
161 if (it->deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
162 it = info_.audioDeviceList.erase(it);
163 } else {
164 ++it;
165 }
166 }
167 SetDeviceAvailable(AudioDeviceType::DEVICE_BLUETOOTH_SCO, false);
168 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
169 TELEPHONY_LOGI("ResetBtAudioDevicesList success");
170 }
171
InitAudioDevice()172 bool AudioDeviceManager::InitAudioDevice()
173 {
174 // when audio deactivate interrupt , reinit
175 // when external audio device connection state changed , reinit
176 auto device = DelayedSingleton<AudioControlManager>::GetInstance()->GetInitAudioDeviceType();
177 return SwitchDevice(device);
178 }
179
ProcessEvent(AudioEvent event)180 bool AudioDeviceManager::ProcessEvent(AudioEvent event)
181 {
182 bool result = false;
183 switch (event) {
184 case AudioEvent::AUDIO_ACTIVATED:
185 case AudioEvent::AUDIO_RINGING:
186 if (!isAudioActivated_) {
187 isAudioActivated_ = true;
188 std::shared_ptr<BluetoothCallManager> bluetoothCallManager = std::make_shared<BluetoothCallManager>();
189 // Gets whether the device can be started from the configuration
190 if (bluetoothCallManager->IsBtAvailble()) {
191 return DelayedSingleton<BluetoothConnection>::GetInstance()->ConnectBtSco();
192 }
193 AudioDevice device = {
194 .deviceType = AudioDeviceType::DEVICE_EARPIECE,
195 .address = { 0 },
196 };
197 if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(device) !=
198 TELEPHONY_SUCCESS) {
199 TELEPHONY_LOGE("current audio device nullptr");
200 return false;
201 }
202 SetCurrentAudioDevice(device.deviceType);
203 }
204 break;
205 case AudioEvent::AUDIO_DEACTIVATED:
206 if (isAudioActivated_) {
207 isAudioActivated_ = false;
208 result = InitAudioDevice();
209 }
210 break;
211 case AudioEvent::INIT_AUDIO_DEVICE:
212 result = InitAudioDevice();
213 break;
214 case AudioEvent::WIRED_HEADSET_DISCONNECTED: {
215 if (!isAudioActivated_) {
216 TELEPHONY_LOGE("call is not active, no need to connect sco");
217 return false;
218 }
219 std::shared_ptr<BluetoothCallManager> bluetoothCallManager = std::make_shared<BluetoothCallManager>();
220 if (bluetoothCallManager->IsBtAvailble()) {
221 return DelayedSingleton<BluetoothConnection>::GetInstance()->ConnectBtSco();
222 }
223 break;
224 }
225 default:
226 break;
227 }
228 return result;
229 }
230
SwitchDevice(AudioEvent event)231 bool AudioDeviceManager::SwitchDevice(AudioEvent event)
232 {
233 auto itFunc = memberFuncMap_.find(event);
234 if (itFunc != memberFuncMap_.end() && itFunc->second != nullptr) {
235 auto memberFunc = itFunc->second;
236 return (this->*memberFunc)();
237 }
238 return false;
239 }
240
ConnectBtScoWithAddress(const std::string & bluetoothAddress)241 bool AudioDeviceManager::ConnectBtScoWithAddress(const std::string &bluetoothAddress)
242 {
243 std::shared_ptr<BluetoothCallManager> bluetoothCallManager = std::make_shared<BluetoothCallManager>();
244 if (bluetoothCallManager->ConnectBtSco(bluetoothAddress)) {
245 return true;
246 }
247 return false;
248 }
249
SwitchDevice(AudioDeviceType device)250 bool AudioDeviceManager::SwitchDevice(AudioDeviceType device)
251 {
252 bool result = false;
253 std::lock_guard<std::mutex> lock(mutex_);
254 switch (device) {
255 case AudioDeviceType::DEVICE_EARPIECE:
256 result = EnableEarpiece();
257 break;
258 case AudioDeviceType::DEVICE_SPEAKER:
259 result = EnableSpeaker();
260 break;
261 case AudioDeviceType::DEVICE_WIRED_HEADSET:
262 result = EnableWiredHeadset();
263 break;
264 case AudioDeviceType::DEVICE_BLUETOOTH_SCO:
265 result = EnableBtSco();
266 break;
267 case AudioDeviceType::DEVICE_DISABLE:
268 result = DisableAll();
269 break;
270 default:
271 break;
272 }
273 TELEPHONY_LOGI("switch device lock release");
274 return result;
275 }
276
EnableSpeaker()277 bool AudioDeviceManager::EnableSpeaker()
278 {
279 if (isSpeakerAvailable_ && DelayedSingleton<AudioProxy>::GetInstance()->SetSpeakerDevActive()) {
280 TELEPHONY_LOGI("speaker enabled , current audio device : speaker");
281 SetCurrentAudioDevice(AudioDeviceType::DEVICE_SPEAKER);
282 return true;
283 }
284 TELEPHONY_LOGI("enable speaker device failed");
285 return false;
286 }
287
EnableEarpiece()288 bool AudioDeviceManager::EnableEarpiece()
289 {
290 if (isEarpieceAvailable_ && DelayedSingleton<AudioProxy>::GetInstance()->SetEarpieceDevActive()) {
291 TELEPHONY_LOGI("earpiece enabled , current audio device : earpiece");
292 SetCurrentAudioDevice(AudioDeviceType::DEVICE_EARPIECE);
293 return true;
294 }
295 TELEPHONY_LOGI("enable earpiece device failed");
296 return false;
297 }
298
EnableWiredHeadset()299 bool AudioDeviceManager::EnableWiredHeadset()
300 {
301 if (isWiredHeadsetConnected_ && DelayedSingleton<AudioProxy>::GetInstance()->SetWiredHeadsetDevActive()) {
302 TELEPHONY_LOGI("wired headset enabled , current audio device : wired headset");
303 SetCurrentAudioDevice(AudioDeviceType::DEVICE_WIRED_HEADSET);
304 return true;
305 }
306 TELEPHONY_LOGI("enable wired headset device failed");
307 return false;
308 }
309
EnableBtSco()310 bool AudioDeviceManager::EnableBtSco()
311 {
312 if (isBtScoConnected_) {
313 TELEPHONY_LOGI("bluetooth sco enabled , current audio device : bluetooth sco");
314 SetCurrentAudioDevice(AudioDeviceType::DEVICE_BLUETOOTH_SCO);
315 return true;
316 }
317 TELEPHONY_LOGI("enable bluetooth sco device failed");
318 return false;
319 }
320
DisableAll()321 bool AudioDeviceManager::DisableAll()
322 {
323 audioDeviceType_ = AudioDeviceType::DEVICE_UNKNOWN;
324 isBtScoDevEnable_ = false;
325 isWiredHeadsetDevEnable_ = false;
326 isSpeakerDevEnable_ = false;
327 isEarpieceDevEnable_ = false;
328 currentAudioDevice_ = std::make_unique<InactiveDeviceState>();
329 if (currentAudioDevice_ == nullptr) {
330 TELEPHONY_LOGE("make_unique InactiveDeviceState failed");
331 return false;
332 }
333 TELEPHONY_LOGI("current audio device : all audio devices disabled");
334 return true;
335 }
336
SetCurrentAudioDevice(AudioDeviceType deviceType)337 void AudioDeviceManager::SetCurrentAudioDevice(AudioDeviceType deviceType)
338 {
339 if (audioDeviceType_ == AudioDeviceType::DEVICE_BLUETOOTH_SCO && audioDeviceType_ != deviceType) {
340 DelayedSingleton<BluetoothConnection>::GetInstance()->DisconnectBtSco();
341 } else if (audioDeviceType_ != AudioDeviceType::DEVICE_BLUETOOTH_SCO &&
342 deviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
343 DelayedSingleton<BluetoothConnection>::GetInstance()->SetBtScoState(SCO_STATE_CONNECTED);
344 }
345 audioDeviceType_ = deviceType;
346 ReportAudioDeviceChange();
347 }
348
ReportAudioDeviceChange()349 int32_t AudioDeviceManager::ReportAudioDeviceChange()
350 {
351 if (audioDeviceType_ == AudioDeviceType::DEVICE_UNKNOWN) {
352 audioDeviceType_ = DelayedSingleton<AudioControlManager>::GetInstance()->GetInitAudioDeviceType();
353 info_.currentAudioDevice.deviceType = audioDeviceType_;
354 } else {
355 info_.currentAudioDevice.deviceType = audioDeviceType_;
356 }
357 std::string address = "";
358 if (audioDeviceType_ == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
359 std::shared_ptr<BluetoothCallManager> bluetoothCallManager = std::make_shared<BluetoothCallManager>();
360 address = bluetoothCallManager->GetConnectedScoAddr();
361 }
362 if (address.length() > kMaxAddressLen) {
363 TELEPHONY_LOGE("address is not too long");
364 return TELEPHONY_ERR_ARGUMENT_INVALID;
365 }
366 if (memcpy_s(info_.currentAudioDevice.address, kMaxAddressLen, address.c_str(), address.length()) != EOK) {
367 TELEPHONY_LOGE("memcpy_s address fail");
368 return TELEPHONY_ERR_MEMCPY_FAIL;
369 }
370 info_.isMuted = DelayedSingleton<AudioProxy>::GetInstance()->IsMicrophoneMute();
371 if (!isAudioActivated_) {
372 TELEPHONY_LOGE("call is not active, no need to report");
373 return TELEPHONY_ERR_ARGUMENT_INVALID;
374 }
375 TELEPHONY_LOGI("report audio device info, currentAudioDeviceType:%{public}d, currentAddress:%{public}s",
376 info_.currentAudioDevice.deviceType, info_.currentAudioDevice.address);
377 return DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAudioDeviceChange(info_);
378 }
379
GetCurrentAudioDevice()380 AudioDeviceType AudioDeviceManager::GetCurrentAudioDevice()
381 {
382 return audioDeviceType_;
383 }
384
IsEarpieceDevEnable()385 bool AudioDeviceManager::IsEarpieceDevEnable()
386 {
387 return isEarpieceDevEnable_;
388 }
389
IsWiredHeadsetDevEnable()390 bool AudioDeviceManager::IsWiredHeadsetDevEnable()
391 {
392 return isWiredHeadsetDevEnable_;
393 }
394
IsSpeakerDevEnable()395 bool AudioDeviceManager::IsSpeakerDevEnable()
396 {
397 return isSpeakerDevEnable_;
398 }
399
IsBtScoDevEnable()400 bool AudioDeviceManager::IsBtScoDevEnable()
401 {
402 return isBtScoDevEnable_;
403 }
404
IsBtScoConnected()405 bool AudioDeviceManager::IsBtScoConnected()
406 {
407 return isBtScoConnected_;
408 }
409
IsWiredHeadsetConnected()410 bool AudioDeviceManager::IsWiredHeadsetConnected()
411 {
412 return isWiredHeadsetConnected_;
413 }
414
IsEarpieceAvailable()415 bool AudioDeviceManager::IsEarpieceAvailable()
416 {
417 return isEarpieceAvailable_;
418 }
419
IsSpeakerAvailable()420 bool AudioDeviceManager::IsSpeakerAvailable()
421 {
422 return isSpeakerAvailable_;
423 }
424
SetDeviceAvailable(AudioDeviceType deviceType,bool available)425 void AudioDeviceManager::SetDeviceAvailable(AudioDeviceType deviceType, bool available)
426 {
427 switch (deviceType) {
428 case AudioDeviceType::DEVICE_SPEAKER:
429 isSpeakerAvailable_ = available;
430 break;
431 case AudioDeviceType::DEVICE_EARPIECE:
432 isEarpieceAvailable_ = available;
433 break;
434 case AudioDeviceType::DEVICE_BLUETOOTH_SCO:
435 isBtScoConnected_ = available;
436 break;
437 case AudioDeviceType::DEVICE_WIRED_HEADSET:
438 isWiredHeadsetConnected_ = available;
439 break;
440 default:
441 break;
442 }
443 }
444 } // namespace Telephony
445 } // namespace OHOS