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