1 /*
2  * Copyright (C) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "bt_fwk_profile_manager"
17 #endif
18 
19 #include "bluetooth_profile_manager.h"
20 
21 #include <atomic>
22 #include <mutex>
23 
24 #include "i_bluetooth_host.h"
25 #include "bluetooth_def.h"
26 #include "bluetooth_host.h"
27 #include "bluetooth_log.h"
28 #include "iservice_registry.h"
29 #include "system_ability_definition.h"
30 #include "bluetooth_no_destructor.h"
31 #include "ohos_bt_gatt.h"
32 
33 namespace OHOS {
34 namespace Bluetooth {
35 
BluetoothProfileManager()36 BluetoothProfileManager::BluetoothProfileManager()
37 {
38     bluetoothSystemAbility_ = new BluetoothSystemAbility();
39     SubScribeBluetoothSystemAbility();
40 }
41 
~BluetoothProfileManager()42 BluetoothProfileManager::~BluetoothProfileManager()
43 {
44     UnSubScribeBluetoothSystemAbility();
45 }
46 
GetInstance()47 BluetoothProfileManager &BluetoothProfileManager::GetInstance()
48 {
49     static BluetoothNoDestructor<BluetoothProfileManager> instance;
50     return *instance;
51 }
52 
SubScribeBluetoothSystemAbility()53 void BluetoothProfileManager::SubScribeBluetoothSystemAbility()
54 {
55     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
56     CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
57     int32_t ret = samgrProxy->SubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
58     CHECK_AND_RETURN_LOG(ret == ERR_OK,
59         "[BLUETOOTH_PROFILE_MANAGER] subscribe systemAbilityId: bluetooth service failed!");
60 }
61 
UnSubScribeBluetoothSystemAbility()62 void BluetoothProfileManager::UnSubScribeBluetoothSystemAbility()
63 {
64     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
65     CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
66     int32_t ret = samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
67     CHECK_AND_RETURN_LOG(ret == ERR_OK,
68         "[BLUETOOTH_PROFILE_MANAGER] Unsubscribe systemAbilityId: bluetooth service failed!");
69 }
70 
GetHostRemote()71 sptr<IRemoteObject> BluetoothProfileManager::GetHostRemote()
72 {
73     sptr<IRemoteObject> value = nullptr;
74     if (profileRemoteMap_.Find(BLUETOOTH_HOST, value)) {
75         return value;
76     }
77     std::lock_guard<std::mutex> lock(needCheckBluetoothServiceOnMutex_);
78     if (!isNeedCheckBluetoothServiceOn_.load()) {
79         HILOGD("Bluetooth service is not start");
80         return value;
81     }
82     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83     CHECK_AND_RETURN_LOG_RET(samgrProxy != nullptr, nullptr, "samgrProxy is nullptr");
84     auto object = samgrProxy->CheckSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
85     if (object == nullptr) {
86         HILOGE("object is nullptr");
87         isNeedCheckBluetoothServiceOn_ = false;
88         return nullptr;
89     }
90     CHECK_AND_RETURN_LOG_RET(object != nullptr, nullptr, "object is nullptr");
91     return object;
92 }
93 
GetProfileRemote(const std::string & objectName)94 sptr<IRemoteObject> BluetoothProfileManager::GetProfileRemote(const std::string &objectName)
95 {
96     std::lock_guard<std::mutex> lock(getProfileRemoteMutex_);
97     sptr<IRemoteObject> remote = nullptr;
98     if (profileRemoteMap_.Find(objectName, remote)) {
99         return remote;
100     } // SafeMap
101     auto hostRemote = GetHostRemote();
102     if (hostRemote == nullptr) {
103         HILOGD("hostRemote is nullptr");
104         return nullptr;
105     }
106     if (objectName == BLUETOOTH_HOST) {
107         remote = hostRemote;
108     } else {
109         sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
110         CHECK_AND_RETURN_LOG_RET(hostProxy != nullptr, nullptr, "hostProxy is nullptr");
111         if (objectName == BLE_ADVERTISER_SERVER || objectName == BLE_CENTRAL_MANAGER_SERVER) {
112             remote = hostProxy->GetBleRemote(objectName);
113         } else {
114             remote = hostProxy->GetProfile(objectName);
115         }
116     }
117     if (remote == nullptr) {
118         HILOGD("remote is nullptr");
119         return nullptr;
120     }
121     profileRemoteMap_.Insert(objectName, remote);
122     return remote;
123 }
124 
NotifyBluetoothStateChange(int32_t transport,int32_t status)125 void BluetoothProfileManager::NotifyBluetoothStateChange(int32_t transport, int32_t status)
126 {
127     if (transport == ADAPTER_BLE && status == STATE_TURN_OFF) {
128         profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
129             // true if *this stores a callcack function target.flase otherwise
130             if (property.functions.bluetoothTurnOffFunc) {
131                 property.functions.bluetoothTurnOffFunc();
132             }
133         });
134     }
135     if (transport == ADAPTER_BLE && status == STATE_TURN_ON) {
136         HILOGD("Clear global variables, return to initial state");
137         ClearGlobalResource();
138         profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
139             if (property.functions.bleTurnOnFunc) {
140                 auto remote = GetProfileRemote(property.objectName);
141                 property.functions.bleTurnOnFunc(remote);
142             }
143         });
144     }
145     return;
146 }
147 
RunFuncWhenBluetoothServiceStarted()148 void BluetoothProfileManager::RunFuncWhenBluetoothServiceStarted()
149 {
150     profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
151         auto remote = GetProfileRemote(property.objectName);
152         if (property.functions.bluetoothLoadedfunc) {
153             property.functions.bluetoothLoadedfunc(remote);
154         }
155     });
156 }
157 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)158 void BluetoothProfileManager::BluetoothSystemAbility::OnAddSystemAbility(int32_t systemAbilityId,
159     const std::string &deviceId)
160 {
161     HILOGI("systemAbilityId:%{public}d", systemAbilityId);
162     switch (systemAbilityId) {
163         case BLUETOOTH_HOST_SYS_ABILITY_ID: {
164             BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = true;
165             {
166                 std::lock_guard<std::mutex> lock(
167                     BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
168                 BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
169             }
170             BluetoothHost::GetDefaultHost().LoadSystemAbilitySuccess(nullptr);
171             BluetoothProfileManager::GetInstance().RunFuncWhenBluetoothServiceStarted();
172             break;
173         }
174         default:
175             HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
176             break;
177     }
178     return;
179 }
180 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)181 void BluetoothProfileManager::BluetoothSystemAbility::OnRemoveSystemAbility(int32_t systemAbilityId,
182     const std::string &deviceId)
183 {
184     HILOGI("systemAbilityId:%{public}d", systemAbilityId);
185     switch (systemAbilityId) {
186         case BLUETOOTH_HOST_SYS_ABILITY_ID: {
187             HILOGD("Clear global variables first");
188             ClearGlobalResource();
189             BluetoothProfileManager::GetInstance().profileRemoteMap_.Clear();
190             BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = false;
191             {
192                 std::lock_guard<std::mutex> lock(
193                     BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
194                 BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
195             }
196             BluetoothHost::GetDefaultHost().OnRemoveBluetoothSystemAbility();
197             break;
198         }
199         default:
200             HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
201             break;
202     }
203     return;
204 }
205 
GetValidId()206 int32_t BluetoothProfileManager::GetValidId()
207 {
208     std::lock_guard<std::mutex> lock(idMutex_);
209     registerValidId_++;
210     return registerValidId_;
211 }
212 
RegisterFunc(const std::string & objectName,std::function<void (sptr<IRemoteObject>)> func)213 int32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName,
214     std::function<void (sptr<IRemoteObject>)> func)
215 {
216     int32_t id = GetValidId();
217     ProfileIdProperty value;
218     ProfileIdProperty idProperties;
219     idProperties.objectName = objectName;
220     idProperties.functions.bluetoothLoadedfunc = func;
221     HILOGD("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
222     profileIdFuncMap_.Insert(id, idProperties);
223     if (isBluetoothServiceOn_) {
224         sptr<IRemoteObject> remote = GetProfileRemote(objectName);
225         CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr"); // 蓝牙已开启,但getremote失败。
226         func(remote);
227     }
228     return id;
229 }
230 
RegisterFunc(const std::string & objectName,ProfileFunctions profileFunctions)231 int32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName, ProfileFunctions profileFunctions)
232 {
233     int32_t id = GetValidId();
234     ProfileIdProperty value;
235     ProfileIdProperty idProperties;
236     idProperties.objectName = objectName;
237     idProperties.functions = profileFunctions;
238     HILOGI("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
239     profileIdFuncMap_.Insert(id, idProperties);
240     if (isBluetoothServiceOn_) {
241         sptr<IRemoteObject> remote = GetProfileRemote(objectName);
242         CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr"); // 蓝牙已开启,但getremote失败。
243         if (profileFunctions.bluetoothLoadedfunc) {
244             profileFunctions.bluetoothLoadedfunc(remote);
245         }
246         if (profileFunctions.bleTurnOnFunc && IS_BLE_ENABLED()) {
247             profileFunctions.bleTurnOnFunc(remote);
248         }
249     }
250     return id;
251 }
252 
DeregisterFunc(int32_t id)253 void BluetoothProfileManager::DeregisterFunc(int32_t id)
254 {
255     HILOGI("id: %{public}d", id);
256     ProfileIdProperty value;
257     CHECK_AND_RETURN_LOG(profileIdFuncMap_.Find(id, value), "id is not exist");
258     profileIdFuncMap_.Erase(id);
259 }
260 
IsBluetoothServiceOn()261 bool BluetoothProfileManager::IsBluetoothServiceOn()
262 {
263     return isBluetoothServiceOn_.load();
264 }
265 } // namespace bluetooth
266 } // namespace OHOS