• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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