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 "bluetooth_connection.h"
17 #include "bluetooth_call_connection.h"
18 #include "audio_control_manager.h"
19 #include "bluetooth_call_manager.h"
20 #include "telephony_log_wrapper.h"
21 #ifdef ABILITY_BLUETOOTH_SUPPORT
22 #include "bluetooth_host.h"
23 #include "bluetooth_audio_manager.h"
24 #include "bluetooth_device.h"
25
26 constexpr int32_t PHONE_NUMBER_TYPE = 0x81;
27 constexpr int32_t VIRTUAL_DEVICE_ADD = 0;
28 constexpr int32_t VIRTUAL_DEVICE_REMOVE = 1;
29 #endif
30
31 namespace OHOS {
32 namespace Telephony {
33 constexpr int32_t DEFAULT_BT_VALUE = -1;
BluetoothConnection()34 BluetoothConnection::BluetoothConnection() : connectedScoAddr_("") {}
35
~BluetoothConnection()36 BluetoothConnection::~BluetoothConnection()
37 {
38 #ifdef ABILITY_BLUETOOTH_SUPPORT
39 if (statusChangeListener_ != nullptr) {
40 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
41 if (samgrProxy != nullptr) {
42 samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
43 statusChangeListener_ = nullptr;
44 }
45 }
46 std::lock_guard<std::mutex> lock(bluetoothMutex_);
47 mapConnectedBtDevices_.clear();
48 #endif
49 }
50
Init()51 void BluetoothConnection::Init()
52 {
53 #ifdef ABILITY_BLUETOOTH_SUPPORT
54 statusChangeListener_ = new (std::nothrow) SystemAbilityListener();
55 if (statusChangeListener_ == nullptr) {
56 TELEPHONY_LOGE("failed to create statusChangeListener");
57 return;
58 }
59 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
60 if (managerPtr == nullptr) {
61 TELEPHONY_LOGE("get system ability manager error");
62 return;
63 }
64 int32_t ret = managerPtr->SubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
65 if (ret != TELEPHONY_SUCCESS) {
66 TELEPHONY_LOGE("failed to subscribe bluetooth service SA:%{public}d", BLUETOOTH_HOST_SYS_ABILITY_ID);
67 return;
68 }
69 std::vector<Bluetooth::BluetoothRemoteDevice> devices;
70 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
71 if (profile == nullptr) {
72 TELEPHONY_LOGE("profile is nullptr");
73 return;
74 }
75 int32_t result = profile->GetConnectedDevices(devices);
76 if (result != TELEPHONY_SUCCESS) {
77 TELEPHONY_LOGE("get connected devices fail");
78 return;
79 }
80 for (auto device : devices) {
81 std::string macAddress = device.GetDeviceAddr();
82 std::string deviceName = device.GetDeviceName();
83 AddBtDevice(macAddress, device);
84 DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(macAddress,
85 AudioDeviceType::DEVICE_BLUETOOTH_SCO, deviceName);
86 }
87 TELEPHONY_LOGI("BluetoothConnection init success!");
88 #endif
89 }
90
91 #ifdef ABILITY_BLUETOOTH_SUPPORT
92
IsBtAvailble()93 bool BluetoothConnection::IsBtAvailble()
94 {
95 std::lock_guard<std::mutex> lock(bluetoothMutex_);
96 if (mapConnectedBtDevices_.empty()) {
97 TELEPHONY_LOGE("mapConnectedBtDevices_ is empty");
98 return false;
99 }
100
101 return true;
102 }
103 #endif
104
SendBtCallState(int32_t numActive,int32_t numHeld,int32_t callState,const std::string & number)105 int32_t BluetoothConnection::SendBtCallState(
106 int32_t numActive, int32_t numHeld, int32_t callState, const std::string &number)
107 {
108 #ifdef ABILITY_BLUETOOTH_SUPPORT
109 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
110 if (profile == nullptr) {
111 TELEPHONY_LOGE("profile is nullptr");
112 return TELEPHONY_ERROR;
113 }
114
115 std::string nickName = "";
116 profile->PhoneStateChanged(numActive, numHeld, callState, number, PHONE_NUMBER_TYPE, nickName);
117 #endif
118 TELEPHONY_LOGI("PhoneStateChanged,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d", numActive, numHeld,
119 callState);
120 return TELEPHONY_SUCCESS;
121 }
122
SendCallDetailsChange(int32_t callId,int32_t callState)123 int32_t BluetoothConnection::SendCallDetailsChange(int32_t callId, int32_t callState)
124 {
125 #ifdef ABILITY_BLUETOOTH_SUPPORT
126 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
127 if (profile == nullptr) {
128 TELEPHONY_LOGE("profile is nullptr");
129 return TELEPHONY_ERROR;
130 }
131
132 profile->CallDetailsChanged(callId, callState);
133 #endif
134 TELEPHONY_LOGI("Send CallDetails");
135 return TELEPHONY_SUCCESS;
136 }
137
IsAudioActivated()138 bool BluetoothConnection::IsAudioActivated()
139 {
140 return DelayedSingleton<AudioControlManager>::GetInstance()->IsAudioActivated();
141 }
142
143 #ifdef ABILITY_BLUETOOTH_SUPPORT
144
ResetBtConnection()145 void BluetoothConnection::ResetBtConnection()
146 {
147 std::lock_guard<std::mutex> lock(bluetoothMutex_);
148 mapConnectedBtDevices_.clear();
149 }
150
RegisterObserver()151 void BluetoothConnection::RegisterObserver()
152 {
153 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
154 if (profile == nullptr) {
155 TELEPHONY_LOGE("BluetoothConnection RegisterObserver fail!");
156 return;
157 }
158
159 profile->RegisterObserver(shared_from_this());
160 }
161
AddBtDevice(const std::string & address,Bluetooth::BluetoothRemoteDevice device)162 void BluetoothConnection::AddBtDevice(const std::string &address, Bluetooth::BluetoothRemoteDevice device)
163 {
164 std::lock_guard<std::mutex> lock(bluetoothMutex_);
165 auto iter = mapConnectedBtDevices_.find(address);
166 if (iter != mapConnectedBtDevices_.end()) {
167 TELEPHONY_LOGI("device is existenced");
168 } else {
169 mapConnectedBtDevices_.insert(std::pair<std::string, const Bluetooth::BluetoothRemoteDevice>(address, device));
170 TELEPHONY_LOGI("AddBtDevice success");
171 }
172 }
173
RemoveBtDevice(const std::string & address)174 void BluetoothConnection::RemoveBtDevice(const std::string &address)
175 {
176 std::lock_guard<std::mutex> lock(bluetoothMutex_);
177 if (mapConnectedBtDevices_.count(address) > 0) {
178 mapConnectedBtDevices_.erase(address);
179 TELEPHONY_LOGI("RemoveBtDevice success");
180 } else {
181 TELEPHONY_LOGE("device is not existenced");
182 }
183 }
184
GetBtDevice(const std::string & address)185 Bluetooth::BluetoothRemoteDevice *BluetoothConnection::GetBtDevice(const std::string &address)
186 {
187 std::lock_guard<std::mutex> lock(bluetoothMutex_);
188 if (mapConnectedBtDevices_.count(address) > 0) {
189 auto iter = mapConnectedBtDevices_.find(address);
190 if (iter != mapConnectedBtDevices_.end()) {
191 return &iter->second;
192 }
193 }
194 TELEPHONY_LOGE("device is not existenced");
195 return nullptr;
196 }
197
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state,int32_t cause)198 void BluetoothConnection::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
199 int32_t state, int32_t cause)
200 {
201 TELEPHONY_LOGI("BluetoothConnection::OnConnectionStateChanged state : %{public}d", state);
202 std::string macAddress = device.GetDeviceAddr();
203 std::string deviceName = device.GetDeviceName();
204 switch (state) {
205 case (int32_t)Bluetooth::BTConnectState::CONNECTED:
206 DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(
207 macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO, deviceName);
208 AddBtDevice(macAddress, device);
209 /** try to connect sco while new bluetooth device connected
210 * if connect sco successfully , should switch current audio device to bluetooth sco
211 */
212 break;
213 case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
214 DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(
215 macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO);
216 RemoveBtDevice(macAddress);
217 break;
218 default:
219 break;
220 }
221 }
222
OnVirtualDeviceChanged(int32_t action,std::string address)223 void BluetoothConnection::OnVirtualDeviceChanged(int32_t action, std::string address)
224 {
225 TELEPHONY_LOGI("BluetoothConnection::OnVirtualDeviceChanged action : %{public}d", action);
226 Bluetooth::BluetoothRemoteDevice device(address);
227 std::string deviceName = device.GetDeviceName();
228 int state = (int32_t)Bluetooth::BTConnectState::DISCONNECTED;
229 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
230 if (profile != nullptr) {
231 profile->GetDeviceState(device, state);
232 } else {
233 TELEPHONY_LOGE("profile is nullptr");
234 return;
235 }
236 switch (action) {
237 case VIRTUAL_DEVICE_ADD:
238 DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(
239 address, AudioDeviceType::DEVICE_BLUETOOTH_SCO, deviceName);
240 AddBtDevice(address, device);
241 /** try to connect sco while new bluetooth device connected
242 * if connect sco successfully , should switch current audio device to bluetooth sco
243 */
244 break;
245 case VIRTUAL_DEVICE_REMOVE:
246 if (state != (int32_t)Bluetooth::BTConnectState::CONNECTED) {
247 DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(
248 address, AudioDeviceType::DEVICE_BLUETOOTH_SCO);
249 RemoveBtDevice(address);
250 }
251 break;
252 default:
253 break;
254 }
255 }
256
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)257 void SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
258 {
259 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
260 if (!CheckInputSysAbilityId(systemAbilityId)) {
261 TELEPHONY_LOGE("added SA is invalid!");
262 return;
263 }
264 if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
265 TELEPHONY_LOGE("added SA is not bluetooth service, ignored.");
266 return;
267 }
268
269 DelayedSingleton<BluetoothConnection>::GetInstance()->RegisterObserver();
270 }
271
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)272 void SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
273 {
274 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
275 if (!CheckInputSysAbilityId(systemAbilityId)) {
276 TELEPHONY_LOGE("removed SA is invalid!");
277 return;
278 }
279 if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
280 TELEPHONY_LOGE("removed SA is not bluetooth service, ignored.");
281 return;
282 }
283 DelayedSingleton<BluetoothCallConnection>::GetInstance()->HfpDisConnectedEndBtCall();
284 DelayedSingleton<BluetoothConnection>::GetInstance()->ResetBtConnection();
285 std::shared_ptr<AudioDeviceManager> audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
286 audioDeviceManager->ResetBtAudioDevicesList();
287 AudioDeviceType currentDeviceType = audioDeviceManager->GetCurrentAudioDevice();
288 if (currentDeviceType == AudioDeviceType::DEVICE_BLUETOOTH_SCO) {
289 TELEPHONY_LOGI("BlueTooth SA removed, init audio device");
290 audioDeviceManager->ProcessEvent(AudioEvent::INIT_AUDIO_DEVICE);
291 }
292 }
293
GetWearBtHeadsetAddress()294 std::string BluetoothConnection::GetWearBtHeadsetAddress()
295 {
296 int32_t cod = DEFAULT_BT_VALUE;
297 int32_t majorClass = DEFAULT_BT_VALUE;
298 int32_t majorMinorClass = DEFAULT_BT_VALUE;
299 std::lock_guard<std::mutex> lock(bluetoothMutex_);
300 for (auto &[address, device] : mapConnectedBtDevices_) {
301 device.GetDeviceProductType(cod, majorClass, majorMinorClass);
302 TELEPHONY_LOGI("Device type majorClass: %{public}d, majorMinorClass: %{public}d.", majorClass, majorMinorClass);
303 bool isWearing = Bluetooth::BluetoothAudioManager::GetInstance().IsDeviceWearing(device);
304 bool isBtHeadset = (majorClass == Bluetooth::BluetoothDevice::MAJOR_AUDIO_VIDEO &&
305 (majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_HEADPHONES ||
306 majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_WEARABLE_HEADSET));
307 if (isWearing && isBtHeadset) {
308 return address;
309 }
310 }
311 TELEPHONY_LOGI("not wearing bt headset");
312 return "";
313 }
314
315 #endif
316 } // namespace Telephony
317 } // namespace OHOS
318