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