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