1 /*
2  * Copyright (C) 2024 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 "bt_connection_manager.h"
17 
18 #include "common_event_manager.h"
19 #include "common_event_support.h"
20 #include "external_deps_proxy.h"
21 #include "infc_service.h"
22 #include "loghelper.h"
23 #include "nfc_service.h"
24 
25 namespace OHOS {
26 namespace NFC {
27 namespace TAG {
28 const uint64_t BT_ENABLE_TIMEOUT = 3000; // ms
29 const uint64_t BT_PAIR_TIMEOUT = 10000; // ms
30 const uint64_t BT_CONNECT_TIMEOUT = 3000; // ms
31 const uint8_t PROFILE_MAX_SIZE = 21;
32 
33 enum BtConnAction {
34     ACTION_INIT = 1,
35     ACTION_DISCONNECT,
36     ACTION_CONNECT
37 };
38 
39 enum BtConnState {
40     STATE_WAITING_FOR_BT_ENABLE = 1,
41     STATE_INIT,
42     STATE_INIT_COMPLETE,
43     STATE_PAIRING,
44     STATE_CONNECTING,
45     STATE_DISCONNECTING,
46     STATE_COMPLETE
47 };
48 
49 enum BtConnResult {
50     CONN_RES_WAITING = 1,
51     CONN_RES_CONNECTED,
52     CONN_RES_DISCONNECTED
53 };
54 
55 static Bluetooth::A2dpSource *g_a2dp;
56 static Bluetooth::HandsFreeAudioGateway *g_hfp;
57 static Bluetooth::HidHost *g_hid;
58 
59 Bluetooth::BluetoothRemoteDevice g_device;
60 std::shared_ptr<BtData> g_btData {};
61 
62 bool g_isStateObserverRegistered = false;
63 bool g_isDevObserverRegistered = false;
64 bool g_isA2dpSupported = false;
65 bool g_isHfpSupported = false;
66 
67 uint8_t g_a2dpConnState = 0;
68 uint8_t g_hfpConnState = 0;
69 uint8_t g_hidConnState = 0;
70 
71 uint8_t g_state = 0;
72 uint8_t g_action = 0;
73 
BtConnectionManager()74 BtConnectionManager::BtConnectionManager()
75 {
76 }
77 
GetInstance()78 BtConnectionManager& BtConnectionManager::GetInstance()
79 {
80     static BtConnectionManager instance;
81     return instance;
82 }
83 
Initialize(std::weak_ptr<NfcService> nfcService)84 void BtConnectionManager::Initialize(std::weak_ptr<NfcService> nfcService)
85 {
86     DebugLog("Init: isInitialized = %{public}d", isInitialized_);
87     if (isInitialized_) {
88         return;
89     }
90     nfcService_ = nfcService;
91     isInitialized_ = true;
92 }
93 
SendMsgToEvtHandler(NfcCommonEvent evt,int64_t delay)94 void BtConnectionManager::SendMsgToEvtHandler(NfcCommonEvent evt, int64_t delay)
95 {
96     if (nfcService_.expired()) {
97         ErrorLog("nfcService expired");
98         return;
99     }
100     if (nfcService_.lock()->eventHandler_ == nullptr) {
101         ErrorLog("event handler is null");
102         return;
103     }
104     DebugLog("SendMsgToEvtHandler: event:%{public}d, delay:%{public}ld", evt, delay);
105     nfcService_.lock()->eventHandler_->SendEvent(static_cast<uint32_t>(evt), delay);
106 }
107 
SendConnMsgToEvtHandler(NfcCommonEvent evt,const Bluetooth::BluetoothRemoteDevice & device,int32_t state,BtProfileType type)108 void BtConnectionManager::SendConnMsgToEvtHandler(NfcCommonEvent evt, const Bluetooth::BluetoothRemoteDevice &device,
109                                                   int32_t state, BtProfileType type)
110 {
111     if (nfcService_.expired()) {
112         ErrorLog("nfcService expired");
113         return;
114     }
115     if (nfcService_.lock()->eventHandler_ == nullptr) {
116         ErrorLog("event handler is null");
117         return;
118     }
119     std::shared_ptr<BtConnectionInfo> info = std::make_shared<BtConnectionInfo>();
120     info->macAddr_ = device.GetDeviceAddr();
121     info->state_ = state;
122     info->type_ = static_cast<uint8_t>(type);
123     DebugLog("SendConnMsgToEvtHandler: event:%{public}d", evt);
124     nfcService_.lock()->eventHandler_->SendEvent(static_cast<uint32_t>(evt), info, 0);
125 }
126 
RemoveMsgFromEvtHandler(NfcCommonEvent evt)127 void BtConnectionManager::RemoveMsgFromEvtHandler(NfcCommonEvent evt)
128 {
129     if (nfcService_.expired()) {
130         ErrorLog("nfcService expired");
131         return;
132     }
133     if (nfcService_.lock()->eventHandler_ == nullptr) {
134         ErrorLog("event handler is null");
135         return;
136     }
137     DebugLog("RemoveMsgFromEvtHandler: event:%{public}d", evt);
138     nfcService_.lock()->eventHandler_->RemoveEvent(static_cast<uint32_t>(evt), static_cast<int64_t>(0));
139 }
140 
RegisterBtObserver()141 void BtConnectionManager::RegisterBtObserver()
142 {
143     std::unique_lock<std::shared_mutex> guard(mutex_);
144     DebugLog("RegisterBtStateObserver");
145     if (btObserver_ == nullptr) {
146         btObserver_ = BtConnectionManager::BtStateObserver::GetInstance();
147     }
148     Bluetooth::BluetoothHost::GetDefaultHost().RegisterObserver(btObserver_);
149     g_isStateObserverRegistered = true;
150 }
151 
UnregisterBtObserverAndProfile()152 void BtConnectionManager::UnregisterBtObserverAndProfile()
153 {
154     DebugLog("UnregisterBtObserverAndProfile");
155     if (btObserver_ != nullptr && g_isStateObserverRegistered) {
156         Bluetooth::BluetoothHost::GetDefaultHost().DeregisterObserver(btObserver_);
157         btObserver_ = nullptr;
158         g_isStateObserverRegistered = false;
159         DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
160     }
161     if (btRemoteDevObserver_ != nullptr && g_isDevObserverRegistered) {
162         Bluetooth::BluetoothHost::GetDefaultHost().DeregisterRemoteDeviceObserver(btRemoteDevObserver_);
163         btRemoteDevObserver_ = nullptr;
164         g_isDevObserverRegistered = false;
165         DebugLog("UnregisterBtObserverAndProfile: bt remote device observer deregistered");
166     }
167     if (g_a2dp != nullptr) {
168         if (btA2dpObserver_) {
169             g_a2dp->DeregisterObserver(btA2dpObserver_);
170             btA2dpObserver_ = nullptr;
171             DebugLog("UnregisterBtObserverAndProfile: bt a2dp observer deregistered");
172         }
173         g_a2dp = nullptr;
174     }
175     if (g_hfp != nullptr) {
176         if (btHfpObserver_) {
177             g_hfp->DeregisterObserver(btHfpObserver_);
178             btHfpObserver_ = nullptr;
179             DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
180         }
181         g_hfp = nullptr;
182     }
183     if (g_hid != nullptr) {
184         if (btHidObserver_) {
185             g_hid->DeregisterObserver(btHidObserver_);
186             btHidObserver_ = nullptr;
187             DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
188         }
189         g_hid = nullptr;
190     }
191 }
192 
193 // lock outside
OnFinish()194 void BtConnectionManager::OnFinish()
195 {
196     DebugLog("OnFinish");
197     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
198     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
199     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT);
200     UnregisterBtObserverAndProfile();
201     g_isStateObserverRegistered = false;
202     g_isDevObserverRegistered = false;
203     g_isA2dpSupported = false;
204     g_isHfpSupported = false;
205     g_a2dpConnState = 0;
206     g_hfpConnState = 0;
207     g_hidConnState = 0;
208     g_state = 0;
209     g_action = 0;
210     g_btData = nullptr;
211 }
212 
HandleBtEnableFailed()213 void BtConnectionManager::HandleBtEnableFailed()
214 {
215     std::unique_lock<std::shared_mutex> guard(mutex_);
216     ErrorLog("Bt Enable Failed");
217     OnFinish();
218 }
219 
HandleBtPairFailed()220 void BtConnectionManager::HandleBtPairFailed()
221 {
222     std::unique_lock<std::shared_mutex> guard(mutex_);
223     ErrorLog("Bt Pair Failed");
224     OnFinish();
225 }
226 
HandleBtConnectFailed()227 void BtConnectionManager::HandleBtConnectFailed()
228 {
229     std::unique_lock<std::shared_mutex> guard(mutex_);
230     ErrorLog("Bt Connect Failed");
231     OnFinish();
232 }
233 
IsBtEnabled()234 bool BtConnectionManager::IsBtEnabled()
235 {
236     std::unique_lock<std::shared_mutex> guard(mutex_);
237     bool isEnabled = Bluetooth::BluetoothHost::GetDefaultHost().IsBrEnabled();
238     InfoLog("IsBtEnabled: %{public}d", isEnabled);
239     return isEnabled;
240 }
241 
HandleEnableBt()242 bool BtConnectionManager::HandleEnableBt()
243 {
244     std::unique_lock<std::shared_mutex> guard(mutex_);
245     DebugLog("HandleEnableBt");
246     if (Bluetooth::BluetoothHost::GetDefaultHost().EnableBle() != Bluetooth::RET_NO_ERROR) { // EnableBt() is desperate
247         ErrorLog("HandleEnableBt: failed");
248         return false;
249     }
250     SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT, BT_ENABLE_TIMEOUT);
251     return true;
252 }
253 
HandleBtPair()254 bool BtConnectionManager::HandleBtPair()
255 {
256     std::unique_lock<std::shared_mutex> guard(mutex_);
257     DebugLog("HandleBtPair");
258     bool isDiscovering = false;
259     Bluetooth::BluetoothHost::GetDefaultHost().IsBtDiscovering(isDiscovering, g_btData->transport_);
260     if (isDiscovering) {
261         InfoLog("Cancel discovery");
262         Bluetooth::BluetoothHost::GetDefaultHost().CancelBtDiscovery();
263     }
264     // oob pair mode currently not supported by bluetooth
265     if (btRemoteDevObserver_ == nullptr) {
266         btRemoteDevObserver_ = std::make_shared<BtRemoteDevObserver>();
267     }
268     Bluetooth::BluetoothHost::GetDefaultHost().RegisterRemoteDeviceObserver(btRemoteDevObserver_);
269     g_isDevObserverRegistered = true;
270 
271     InfoLog("Handle bt pair start");
272     g_device.StartCrediblePair();
273     SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT, BT_PAIR_TIMEOUT);
274     return true;
275 }
276 
IsA2dpSupported()277 bool BtConnectionManager::IsA2dpSupported()
278 {
279     if (g_btData == nullptr) {
280         ErrorLog("IsA2dpSupported: g_btData error");
281         return false;
282     }
283     for (Bluetooth::UUID uuid : g_btData->uuids_) {
284         if ((uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_A2DP_SINK) == 0) ||
285             (uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_AVRCP_CT) == 0)) {
286             return true;
287         }
288     }
289     return g_btData->btClass_.IsProfileSupported(Bluetooth::PROFILE_ID_A2DP_SRC);
290 }
291 
IsHfpSupported()292 bool BtConnectionManager::IsHfpSupported()
293 {
294     if (g_btData == nullptr) {
295         ErrorLog("IsHfpSupported: g_btData error");
296         return false;
297     }
298     for (Bluetooth::UUID uuid : g_btData->uuids_) {
299         if ((uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_HFP_AG) == 0) ||
300             (uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_HFP_HF) == 0)) {
301             return true;
302         }
303     }
304     return g_btData->btClass_.IsProfileSupported(Bluetooth::PROFILE_ID_HFP_AG);
305 }
306 
307 // false to OnFinish()
HandleBtInit()308 bool BtConnectionManager::HandleBtInit()
309 {
310     std::unique_lock<std::shared_mutex> guard(mutex_);
311     if (g_btData == nullptr) {
312         ErrorLog("HandleBtInit: g_btData error");
313         return false;
314     }
315     if (g_device.GetDeviceAddr().compare(g_btData->macAddress_) != 0) {
316         g_device = Bluetooth::BluetoothRemoteDevice(g_btData->macAddress_, g_btData->transport_);
317     }
318     if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
319         InfoLog("Init: hid getprofile");
320         if (g_hid == nullptr) {
321             g_hid = Bluetooth::HidHost::GetProfile();
322         }
323     } else {
324         if (g_a2dp == nullptr) {
325             g_a2dp = Bluetooth::A2dpSource::GetProfile();
326         }
327         if (g_hfp == nullptr) {
328             g_hfp = Bluetooth::HandsFreeAudioGateway::GetProfile();
329         }
330         g_isA2dpSupported = IsA2dpSupported();
331         g_isHfpSupported = IsHfpSupported();
332         InfoLog("Init:a2dp: %{public}d, hfp: %{public}d", g_isA2dpSupported, g_isHfpSupported);
333         if (!g_isA2dpSupported && !g_isHfpSupported) {
334             // if both not supported, maybe the info is empty in ndef
335             // try both
336             g_isA2dpSupported = true;
337             g_isHfpSupported = true;
338             InfoLog("Init:a2dp and hid not supported");
339         }
340     }
341     return true;
342 }
343 
344 // false to OnFinish()
DecideInitNextAction()345 bool BtConnectionManager::DecideInitNextAction()
346 {
347     std::unique_lock<std::shared_mutex> guard(mutex_);
348     if (g_btData == nullptr) {
349         ErrorLog("HandleBtInit: g_btData error");
350         return false;
351     }
352     int32_t state = 0;
353     if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
354         if (!g_hid) {
355             ErrorLog("DecideInitNextAction: hid not supported");
356             return false;
357         }
358         g_hid->GetDeviceState(g_device, state);
359         InfoLog("DecideInitNextAction: hid device state: %{public}d", state);
360         if (state == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
361             g_action = ACTION_DISCONNECT;
362         } else {
363             g_action = ACTION_CONNECT;
364         }
365     } else {
366         if (g_a2dp && g_isA2dpSupported) {
367             g_a2dp->GetDeviceState(g_device, state);
368         }
369 
370         InfoLog("DecideInitNextAction: a2dp device state: %{public}d", state);
371         if (state == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
372             g_action = ACTION_DISCONNECT;
373         } else {
374             // unconnected a2dp and all hfp go to connect action
375             g_action = ACTION_CONNECT;
376         }
377     }
378     return true;
379 }
380 
GetProfileList()381 bool BtConnectionManager::GetProfileList()
382 {
383     std::unique_lock<std::shared_mutex> guard(mutex_);
384     std::vector<uint32_t> profileList = Bluetooth::BluetoothHost::GetDefaultHost().GetProfileList();
385     if (profileList.size() == 0 && profileList.size() > PROFILE_MAX_SIZE) {
386         ErrorLog("profile list size error");
387         return false;
388     }
389     for (uint32_t i = 0; i < profileList.size(); i++) {
390         if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE &&
391             profileList[i] == Bluetooth::PROFILE_ID_HID_HOST) {
392             InfoLog("PROFILE_ID_HID_HOST");
393             return true;
394         } else {
395             if (profileList[i] == Bluetooth::PROFILE_ID_A2DP_SRC ||
396                 profileList[i] == Bluetooth::PROFILE_ID_HFP_AG) {
397                 InfoLog("PROFILE_ID_A2DP_SRC OR PROFILE_ID_HFP_AG");
398                 return true;
399             }
400         }
401     }
402     return false;
403 }
404 
NextActionInit()405 void BtConnectionManager::NextActionInit()
406 {
407     InfoLog("NextActionInit: g_state: %{public}d", g_state);
408     if (g_state == STATE_WAITING_FOR_BT_ENABLE) {
409         return;
410     }
411     if (g_state == STATE_INIT) {
412         if (!GetProfileList()) {
413             ErrorLog("NextActionInit: GetProfileList error");
414             return OnFinish();
415         }
416         if (!HandleBtInit()) {
417             ErrorLog("NextActionInit: HandleBtInit error");
418             return OnFinish();
419         }
420         if (!DecideInitNextAction()) {
421             ErrorLog("NextActionInit: DecideInitNextAction error");
422             return OnFinish();
423         }
424         g_state = STATE_INIT_COMPLETE;
425     }
426     NextAction();
427 }
428 
RegisterProfileObserver(BtProfileType type)429 void BtConnectionManager::RegisterProfileObserver(BtProfileType type)
430 {
431     InfoLog("RegisterProfileObserver type: %{public}d", type);
432     switch (type) {
433         case A2DP_SRC: {
434             if (!g_a2dp || !g_isA2dpSupported) {
435                 ErrorLog("RegisterProfileObserver: a2dp error");
436                 break;
437             }
438             if (!btA2dpObserver_) {
439                 btA2dpObserver_ = std::make_shared<BtA2dpObserver>();
440                 g_a2dp->RegisterObserver(btA2dpObserver_);
441             }
442             break;
443         }
444         case HFP_AG: {
445             if (!g_hfp || !g_isHfpSupported) {
446                 ErrorLog("RegisterProfileObserver: hfp error");
447                 break;
448             }
449             if (!btHfpObserver_) {
450                 btHfpObserver_ = std::make_shared<BtHfpObserver>();
451                 g_hfp->RegisterObserver(btHfpObserver_);
452             }
453             break;
454         }
455         case HID_HOST: {
456             if (!g_hid) {
457                 ErrorLog("RegisterProfileObserver: hid error");
458                 break;
459             }
460             if (!btHidObserver_) {
461                 btHidObserver_ = std::make_shared<BtHidObserver>();
462                 g_hid->RegisterObserver(btHidObserver_);
463             }
464             break;
465         }
466         default:
467             break;
468     }
469 }
470 
471 // true for need wait, false for go to NextStep
HandleBtConnect()472 bool BtConnectionManager::HandleBtConnect()
473 {
474     std::unique_lock<std::shared_mutex> guard(mutex_);
475     DebugLog("HandleBtConnect");
476     int32_t state = 0;
477     if (g_hfp) {
478         g_hfp->GetDeviceState(g_device, state);
479         InfoLog("HandleBtConnect: hfp state = %{public}d", state);
480         if (state != static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
481             if (g_isHfpSupported) {
482                 g_hfpConnState = BtConnResult::CONN_RES_WAITING;
483                 RegisterProfileObserver(HFP_AG);
484                 InfoLog("HandleBtConnect: hfp connect start");
485                 g_hfp->Connect(g_device);
486             } else {
487                 g_hfpConnState = BtConnResult::CONN_RES_DISCONNECTED;
488                 InfoLog("HandleBtConnect: hfp disconnected");
489             }
490         } else {
491             g_hfpConnState = BtConnResult::CONN_RES_CONNECTED;
492             InfoLog("HandleBtConnect: hfp connected");
493         }
494     }
495     if (g_a2dp) {
496         g_a2dp->GetDeviceState(g_device, state);
497         InfoLog("HandleBtConnect: a2dp state = %{public}d", state);
498         if (state != static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
499             if (g_isA2dpSupported) {
500                 g_a2dpConnState = BtConnResult::CONN_RES_WAITING;
501                 RegisterProfileObserver(A2DP_SRC);
502                 InfoLog("HandleBtConnect: a2dp connect start");
503                 g_a2dp->Connect(g_device);
504             } else {
505                 g_a2dpConnState = BtConnResult::CONN_RES_DISCONNECTED;
506                 InfoLog("HandleBtConnect: a2dp disconnected");
507             }
508         } else {
509             g_a2dpConnState = BtConnResult::CONN_RES_CONNECTED;
510             InfoLog("HandleBtConnect: a2dp connected");
511         }
512     }
513     if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
514         g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
515         InfoLog("HandleBtConnect: waiting for connect result");
516         SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT, BT_CONNECT_TIMEOUT);
517         return true;
518     }
519     return false;
520 }
521 
522 // true for need wait, false for go to OnFinish()
HandleBtConnectWaiting()523 bool BtConnectionManager::HandleBtConnectWaiting()
524 {
525     std::unique_lock<std::shared_mutex> guard(mutex_);
526     if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
527         g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
528         InfoLog("HandleBtConnectWaiting: waiting for connect result");
529         return true;
530     }
531     if (g_a2dpConnState == BtConnResult::CONN_RES_CONNECTED ||
532         g_hfpConnState == BtConnResult::CONN_RES_CONNECTED) {
533         InfoLog("HandleBtConnectWaiting: connect success");
534         g_device.SetDeviceAlias(g_btData->name_);
535         return false;
536     } else {
537         // connect failed
538         return false;
539     }
540 }
541 
NextActionConnect()542 void BtConnectionManager::NextActionConnect()
543 {
544     int pairState = 0;
545     g_device.GetPairState(pairState);
546     InfoLog("NextActionConnect: state: %{public}d, pairState: %{public}d", g_state, pairState);
547     switch (g_state) {
548         case STATE_INIT_COMPLETE: {
549             if (pairState != Bluetooth::PAIR_PAIRED) {
550                 g_state = STATE_PAIRING;
551                 HandleBtPair();
552                 break;
553             }
554             // fall-through
555             // when already paired
556         }
557         case STATE_PAIRING: {
558             g_state = STATE_CONNECTING;
559             if (g_btData->transport_ != Bluetooth::GATT_TRANSPORT_TYPE_LE) {
560                 if (HandleBtConnect()) {
561                     InfoLog("connecting, need wait");
562                     break;
563                 }
564             }
565             // fall-through
566             // when transport not LE or connect success
567         }
568         case STATE_CONNECTING: {
569             if (g_btData->transport_ != Bluetooth::GATT_TRANSPORT_TYPE_LE) {
570                 if (!HandleBtConnectWaiting()) {
571                     OnFinish();
572                 }
573             }
574             break;
575         }
576         default:
577             break;
578     }
579 }
580 
581 // true for need wait, false for go to NextStep
HandleBtDisconnect()582 bool BtConnectionManager::HandleBtDisconnect()
583 {
584     std::unique_lock<std::shared_mutex> guard(mutex_);
585     DebugLog("HandleBtDisconnect");
586     int32_t devState = 0;
587     if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
588         if (!g_hid) {
589             return false;
590         }
591         g_hid->GetDeviceState(g_device, devState);
592         if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
593             g_hidConnState = BtConnResult::CONN_RES_WAITING;
594             RegisterProfileObserver(HID_HOST);
595             InfoLog("HandleBtDisconnect: hid disconnect start");
596             g_hid->Disconnect(g_device);
597             return true;
598         } else {
599             g_hidConnState = BtConnResult::CONN_RES_DISCONNECTED;
600             InfoLog("HandleBtDisconnect: hfp disconnect");
601         }
602     } else {
603         if (g_hfp && g_isHfpSupported) {
604             g_hfp->GetDeviceState(g_device, devState);
605             if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
606                 g_hfpConnState = BtConnResult::CONN_RES_WAITING;
607                 RegisterProfileObserver(HFP_AG);
608                 InfoLog("HandleBtDisconnect: hfp disconnect start");
609             } else {
610                 g_hfpConnState = BtConnResult::CONN_RES_DISCONNECTED;
611                 InfoLog("HandleBtDisconnect: hfp disconnected");
612             }
613         }
614         if (g_a2dp && g_isA2dpSupported) {
615             g_a2dp->GetDeviceState(g_device, devState);
616             if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
617                 g_a2dpConnState = BtConnResult::CONN_RES_WAITING;
618                 RegisterProfileObserver(A2DP_SRC);
619                 InfoLog("HandleBtDisconnect: a2dp disconnect start");
620             } else {
621                 g_a2dpConnState = BtConnResult::CONN_RES_DISCONNECTED;
622                 InfoLog("HandleBtDisconnect: a2dp disconnected");
623             }
624         }
625         if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
626             g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
627             Bluetooth::BluetoothHost::GetDefaultHost().DisconnectAllowedProfiles(g_btData->macAddress_);
628             InfoLog("HandleBtDisconnect: waiting for disconnect result");
629             return true;
630         }
631     }
632     return false;
633 }
634 
635 // true for need wait, false for go to OnFinish()
HandleBtDisconnectWaiting()636 bool BtConnectionManager::HandleBtDisconnectWaiting()
637 {
638     std::unique_lock<std::shared_mutex> guard(mutex_);
639     if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
640         if (g_hidConnState == BtConnResult::CONN_RES_DISCONNECTED) {
641             InfoLog("HandleBtDisconnectWaiting:hid disconnected");
642             return false;
643         }
644     } else {
645         if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
646             g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
647             InfoLog("HandleBtDisconnectWaiting: waiting for disconnect result");
648             return true;
649         }
650         if (g_a2dpConnState == BtConnResult::CONN_RES_DISCONNECTED &&
651             g_hfpConnState == BtConnResult::CONN_RES_DISCONNECTED) {
652             InfoLog("HandleBtDisconnectWaiting: disconnect success");
653             return false;
654         }
655     }
656     return false;
657 }
658 
NextActionDisconnect()659 void BtConnectionManager::NextActionDisconnect()
660 {
661     int pairState = 0;
662     g_device.GetPairState(pairState);
663     InfoLog("NextActionConnect: state: %{public}d, pairState: %{public}d", g_state, pairState);
664     switch (g_state) {
665         case STATE_INIT_COMPLETE: {
666             g_state = STATE_DISCONNECTING;
667             if (HandleBtDisconnect()) {
668                 InfoLog("NextActionConnect: disconnecting need wait");
669                 break;
670             }
671             // fall-through
672             // when already disconnected
673         }
674         case STATE_DISCONNECTING: {
675             if (!HandleBtDisconnectWaiting()) {
676                 OnFinish();
677             }
678             break;
679         }
680         default:
681             break;
682     }
683 }
684 
NextAction()685 void BtConnectionManager::NextAction()
686 {
687     InfoLog("NextAction: state: %{public}d action: %{public}d", g_state, g_action);
688     switch (g_action) {
689         case ACTION_INIT:
690             NextActionInit();
691             break;
692         case ACTION_CONNECT:
693             NextActionConnect();
694             break;
695         case ACTION_DISCONNECT:
696             NextActionDisconnect();
697             break;
698         default:
699             break;
700     }
701 }
702 
TryPairBt(std::shared_ptr<BtData> data)703 void BtConnectionManager::TryPairBt(std::shared_ptr<BtData> data)
704 {
705     std::unique_lock<std::shared_mutex> guard(mutex_);
706     if (!data || !data->isValid_) {
707         ErrorLog("data invalid");
708         return;
709     }
710     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
711     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
712     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT);
713     g_btData = data;
714     InfoLog("TryPairBt: Publish notification name: %{private}s", data->name_.c_str());
715     ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_BT_NOTIFICATION_ID, data->name_, 0);
716 }
717 
OnBtNtfClicked()718 void BtConnectionManager::OnBtNtfClicked()
719 {
720     InfoLog("OnBtNtfClicked");
721     if (g_btData == nullptr) {
722         ErrorLog("OnBtNtfClicked: g_btData error");
723         return;
724     }
725     RegisterBtObserver();
726     g_action = ACTION_INIT;
727     if (IsBtEnabled()) {
728         g_state = STATE_INIT;
729         NextAction();
730     } else {
731         g_state = STATE_WAITING_FOR_BT_ENABLE;
732         if (!HandleEnableBt()) {
733             ErrorLog("OnBtNtfClicked enable bt failed");
734             OnFinish();
735         }
736     }
737 }
738 
OnBtEnabled()739 void BtConnectionManager::OnBtEnabled()
740 {
741     DebugLog("OnBtEnabled");
742     RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
743     if (g_state == STATE_WAITING_FOR_BT_ENABLE) {
744         g_state = STATE_INIT;
745         NextAction();
746     }
747 }
748 
OnStateChanged(const int transport,const int status)749 void BtConnectionManager::BtStateObserver::OnStateChanged(const int transport, const int status)
750 {
751     InfoLog("OnStateChanged transport: %{public}d, status: %{public}d", transport, status);
752     if (transport == static_cast<int>(Bluetooth::BTTransport::ADAPTER_BREDR) &&
753         status == static_cast<int>(Bluetooth::STATE_TURN_ON)) {
754         BtConnectionManager::GetInstance().OnBtEnabled();
755     }
756 }
757 
OnPairStatusChanged(std::shared_ptr<BtConnectionInfo> info)758 void BtConnectionManager::OnPairStatusChanged(std::shared_ptr<BtConnectionInfo> info)
759 {
760     if (info == nullptr) {
761         ErrorLog("OnPairStatusChanged: info is null");
762         return;
763     }
764     if (g_btData == nullptr) {
765         ErrorLog("OnPairStatusChanged: g_btData error");
766         return;
767     }
768     if (info->macAddr_.compare(g_btData->macAddress_) != 0) {
769         ErrorLog("OnPairStatusChanged not same device");
770         return;
771     }
772     if (g_state == STATE_PAIRING) {
773         if (info->state_ == Bluetooth::PAIR_PAIRED) {
774             RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
775             NextAction();
776         } else if (info->state_ == Bluetooth::PAIR_NONE) {
777             // timeout msg removed in OnFinish()
778             OnFinish();
779         }
780     }
781 }
782 
OnPairStatusChanged(const Bluetooth::BluetoothRemoteDevice & device,int status,int cause)783 void BtConnectionManager::BtRemoteDevObserver::OnPairStatusChanged(const Bluetooth::BluetoothRemoteDevice &device,
784                                                                    int status, int cause)
785 {
786     (void)cause; // Unused parameter
787     InfoLog("OnPairStatusChanged status: %{public}d", status);
788     BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_PAIR_STATUS_CHANGED,
789         device, status, BtConnectionManager::BtProfileType::A2DP_SRC);
790 }
791 
OnConnectionStateChanged(std::shared_ptr<BtConnectionInfo> info)792 void BtConnectionManager::OnConnectionStateChanged(std::shared_ptr<BtConnectionInfo> info)
793 {
794     if (info == nullptr) {
795         ErrorLog("OnConnectionStateChanged: info is null");
796         return;
797     }
798     if (g_btData == nullptr) {
799         ErrorLog("OnConnectionStateChanged: g_btData error");
800         return;
801     }
802     if (info->macAddr_.compare(g_btData->macAddress_) != 0) {
803         ErrorLog("OnConnectionStateChanged not same device");
804         return;
805     }
806     if (info->state_ == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
807         {
808             std::unique_lock<std::shared_mutex> guard(mutex_);
809             if (info->type_ == static_cast<uint8_t>(HFP_AG)) {
810                 g_hfpConnState = CONN_RES_CONNECTED;
811             } else if (info->type_ == static_cast<uint8_t>(A2DP_SRC)) {
812                 g_a2dpConnState = CONN_RES_CONNECTED;
813             } else if (info->type_ == static_cast<uint8_t>(HID_HOST)) {
814                 g_hidConnState = CONN_RES_CONNECTED;
815             }
816         }
817         NextAction();
818     } else if (info->state_ == static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
819         {
820             std::unique_lock<std::shared_mutex> guard(mutex_);
821             if (g_action == ACTION_CONNECT) {
822                 // need retry
823                 return;
824             }
825             if (info->type_ == static_cast<uint8_t>(HFP_AG)) {
826                 g_hfpConnState = CONN_RES_DISCONNECTED;
827             } else if (info->type_ == static_cast<uint8_t>(A2DP_SRC)) {
828                 g_a2dpConnState = CONN_RES_DISCONNECTED;
829             } else if (info->type_ == static_cast<uint8_t>(HID_HOST)) {
830                 g_hidConnState = CONN_RES_DISCONNECTED;
831             }
832         }
833         NextAction();
834     }
835 }
836 
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state,int32_t cause)837 void BtConnectionManager::BtA2dpObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
838                                                                    int32_t state, int32_t cause)
839 {
840     (void)cause; // Unused param
841     InfoLog("BtA2dpObserver::OnConnectionStateChanged state: %{public}d", state);
842     BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
843         device, state, BtConnectionManager::BtProfileType::A2DP_SRC);
844 }
845 
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state,int32_t cause)846 void BtConnectionManager::BtHfpObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
847                                                                   int32_t state, int32_t cause)
848 {
849     (void)cause; // Unused param
850     InfoLog("BtHfpObserver::OnConnectionStateChanged state: %{public}d", state);
851     BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
852         device, state, BtConnectionManager::BtProfileType::HFP_AG);
853 }
854 
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int state,int cause)855 void BtConnectionManager::BtHidObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
856                                                                   int state, int cause)
857 {
858     (void)cause; // Unused param
859     InfoLog("BtHidObserver::OnConnectionStateChanged state: %{public}d", state);
860     BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
861         device, state, BtConnectionManager::BtProfileType::HID_HOST);
862 }
863 } // namespace TAG
864 } // namespace NFC
865 } // namespace OHOS
866