1 /*
2 * Copyright (C) 2022 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_hid_host.h"
17 #include <unistd.h>
18 #include "bluetooth_device.h"
19 #include "bluetooth_host.h"
20 #include "bluetooth_profile_manager.h"
21 #include "bluetooth_log.h"
22 #include "bluetooth_observer_list.h"
23 #include "bluetooth_hid_host_observer_stub.h"
24 #include "bluetooth_utils.h"
25 #include "i_bluetooth_hid_host.h"
26 #include "i_bluetooth_host.h"
27 #include "iservice_registry.h"
28 #include "system_ability_definition.h"
29
30 namespace OHOS {
31 namespace Bluetooth {
32 std::mutex g_hidProxyMutex;
33 class HidHostInnerObserver : public BluetoothHidHostObserverStub {
34 public:
HidHostInnerObserver(BluetoothObserverList<HidHostObserver> &observers)35 explicit HidHostInnerObserver(BluetoothObserverList<HidHostObserver> &observers) : observers_(observers)
36 {
37 HILOGD("Enter!");
38 }
39 ~HidHostInnerObserver() override
40 {
41 HILOGD("Enter!");
42 }
43
44 ErrCode OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
45 {
46 HILOGD("hid conn state, device: %{public}s, state: %{public}s, cause: %{public}d",
47 GET_ENCRYPT_RAW_ADDR(device), GetProfileConnStateName(state).c_str(), cause);
48 BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
49 observers_.ForEach([remoteDevice, state, cause](std::shared_ptr<HidHostObserver> observer) {
50 observer->OnConnectionStateChanged(remoteDevice, state, cause);
51 });
52 return NO_ERROR;
53 }
54
55 private:
56 BluetoothObserverList<HidHostObserver> &observers_;
57 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(HidHostInnerObserver);
58 };
59
60 struct HidHost::impl {
61 impl();
62 ~impl();
63
GetDevicesByStatesOHOS::Bluetooth::HidHost::impl64 int32_t GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice>& result)
65 {
66 HILOGI("Enter!");
67 std::vector<BluetoothRawAddress> rawDevices;
68 std::vector<int32_t> tmpStates;
69 for (int32_t state : states) {
70 tmpStates.push_back((int32_t)state);
71 }
72 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
73 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy");
74 int32_t ret = proxy->GetDevicesByStates(tmpStates, rawDevices);
75 if (ret != BT_NO_ERROR) {
76 HILOGE("inner error.");
77 return ret;
78 }
79
80 for (BluetoothRawAddress rawDevice : rawDevices) {
81 BluetoothRemoteDevice remoteDevice(rawDevice.GetAddress(), 1);
82 result.push_back(remoteDevice);
83 }
84
85 return BT_NO_ERROR;
86 }
87
GetDeviceStateOHOS::Bluetooth::HidHost::impl88 int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
89 {
90 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
91 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
92 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
93 HILOGE("invalid param.");
94 return BT_ERR_INVALID_PARAM;
95 }
96
97 return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
98 }
99
ConnectOHOS::Bluetooth::HidHost::impl100 int32_t Connect(const BluetoothRemoteDevice &device)
101 {
102 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
103 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
104 HILOGE("invalid param.");
105 return BT_ERR_INVALID_PARAM;
106 }
107 HILOGI("hid connect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
108 return proxy->Connect(BluetoothRawAddress(device.GetDeviceAddr()));
109 }
110
DisconnectOHOS::Bluetooth::HidHost::impl111 int32_t Disconnect(const BluetoothRemoteDevice &device)
112 {
113 HILOGI("hid disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
114 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
115 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
116 HILOGE("invalid param.");
117 return BT_ERR_INVALID_PARAM;
118 }
119
120 return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
121 }
122
RegisterObserverOHOS::Bluetooth::HidHost::impl123 void RegisterObserver(std::shared_ptr<HidHostObserver> observer)
124 {
125 HILOGD("Enter!");
126 observers_.Register(observer);
127 }
128
DeregisterObserverOHOS::Bluetooth::HidHost::impl129 void DeregisterObserver(std::shared_ptr<HidHostObserver> observer)
130 {
131 HILOGI("Enter!");
132 observers_.Deregister(observer);
133 }
134
HidHostVCUnplugOHOS::Bluetooth::HidHost::impl135 void HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
136 {
137 HILOGI("Enter!");
138 int result;
139 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
140 if (proxy != nullptr) {
141 proxy->HidHostVCUnplug(device, id, size, type, result);
142 }
143 }
144
HidHostSendDataOHOS::Bluetooth::HidHost::impl145 void HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)
146 {
147 HILOGI("Enter!");
148 int result;
149 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
150 if (proxy != nullptr) {
151 proxy->HidHostSendData(device, id, size, type, result);
152 }
153 }
154
HidHostSetReportOHOS::Bluetooth::HidHost::impl155 void HidHostSetReport(std::string device, uint8_t type, std::string &report)
156 {
157 HILOGI("Enter!");
158 int result;
159 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
160 if (proxy != nullptr) {
161 proxy->HidHostSetReport(device, type, report, result);
162 }
163 }
164
HidHostGetReportOHOS::Bluetooth::HidHost::impl165 void HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
166 {
167 HILOGI("Enter!");
168 int result;
169 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
170 if (proxy != nullptr && IS_BT_ENABLED()) {
171 proxy->HidHostGetReport(device, id, size, type, result);
172 }
173 }
174
SetConnectStrategyOHOS::Bluetooth::HidHost::impl175 int SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
176 {
177 HILOGI("enter");
178 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
179 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
180 return proxy->SetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
181 }
182
GetConnectStrategyOHOS::Bluetooth::HidHost::impl183 int GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
184 {
185 HILOGI("enter");
186 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
187 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
188 return proxy->GetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
189 }
190
191 int32_t profileRegisterId = 0;
192 private:
193 BluetoothObserverList<HidHostObserver> observers_;
194 sptr<HidHostInnerObserver> innerObserver_;
195 };
196
impl()197 HidHost::impl::impl()
198 {
199 innerObserver_ = new HidHostInnerObserver(observers_);
200 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_HID_HOST_SERVER,
201 [this](sptr<IRemoteObject> remote) {
202 sptr<IBluetoothHidHost> proxy = iface_cast<IBluetoothHidHost>(remote);
203 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
204 proxy->RegisterObserver(innerObserver_);
205 });
206 }
207
~impl()208 HidHost::impl::~impl()
209 {
210 HILOGD("start");
211 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
212 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
213 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
214 proxy->DeregisterObserver(innerObserver_);
215 }
216
HidHost()217 HidHost::HidHost()
218 {
219 pimpl = std::make_unique<impl>();
220 }
221
~HidHost()222 HidHost::~HidHost() {}
223
GetProfile()224 HidHost *HidHost::GetProfile()
225 {
226 #ifdef DTFUZZ_TEST
227 static BluetoothNoDestructor<HidHost> instance;
228 return instance.get();
229 #else
230 static HidHost instance;
231 return &instance;
232 #endif
233 }
234
GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)235 int32_t HidHost::GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)
236 {
237 if (!IS_BT_ENABLED()) {
238 HILOGE("bluetooth is off.");
239 return BT_ERR_INVALID_STATE;
240 }
241
242 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
243 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
244
245 return pimpl->GetDevicesByStates(states, result);
246 }
247
GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)248 int32_t HidHost::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
249 {
250 if (!IS_BT_ENABLED()) {
251 HILOGE("bluetooth is off.");
252 return BT_ERR_INVALID_STATE;
253 }
254
255 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
256 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
257
258 return pimpl->GetDeviceState(device, state);
259 }
260
Connect(const BluetoothRemoteDevice &device)261 int32_t HidHost::Connect(const BluetoothRemoteDevice &device)
262 {
263 if (!IS_BT_ENABLED()) {
264 HILOGE("bluetooth is off.");
265 return BT_ERR_INVALID_STATE;
266 }
267
268 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
269 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
270
271 return pimpl->Connect(device);
272 }
273
Disconnect(const BluetoothRemoteDevice &device)274 int32_t HidHost::Disconnect(const BluetoothRemoteDevice &device)
275 {
276 if (!IS_BT_ENABLED()) {
277 HILOGE("bluetooth is off.");
278 return BT_ERR_INVALID_STATE;
279 }
280
281 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
282 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
283
284 return pimpl->Disconnect(device);
285 }
286
SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)287 int HidHost::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
288 {
289 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
290 if (!IS_BT_ENABLED()) {
291 HILOGE("bluetooth is off.");
292 return BT_ERR_INVALID_STATE;
293 }
294
295 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
296 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
297
298 if ((!device.IsValidBluetoothRemoteDevice()) || (
299 (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
300 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
301 HILOGI("input parameter error.");
302 return BT_ERR_INVALID_PARAM;
303 }
304 return pimpl->SetConnectStrategy(device, strategy);
305 }
306
GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const307 int HidHost::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
308 {
309 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
310 if (!IS_BT_ENABLED()) {
311 HILOGE("bluetooth is off.");
312 return BT_ERR_INVALID_STATE;
313 }
314
315 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
316 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
317
318 if (!device.IsValidBluetoothRemoteDevice()) {
319 HILOGI("input parameter error.");
320 return BT_ERR_INVALID_PARAM;
321 }
322 return pimpl->GetConnectStrategy(device, strategy);
323 }
324
RegisterObserver(std::shared_ptr<HidHostObserver> observer)325 void HidHost::RegisterObserver(std::shared_ptr<HidHostObserver> observer)
326 {
327 HILOGD("enter");
328 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
329 pimpl->RegisterObserver(observer);
330 }
331
DeregisterObserver(std::shared_ptr<HidHostObserver> observer)332 void HidHost::DeregisterObserver(std::shared_ptr<HidHostObserver> observer)
333 {
334 HILOGD("enter");
335 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
336 pimpl->DeregisterObserver(observer);
337 }
338
HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)339 void HidHost::HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
340 {
341 if (!IS_BT_ENABLED()) {
342 HILOGE("bluetooth is off.");
343 return;
344 }
345 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
346 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
347
348 return pimpl->HidHostVCUnplug(device, id, size, type);
349 }
350
HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)351 void HidHost::HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)
352 {
353 if (!IS_BT_ENABLED()) {
354 HILOGE("bluetooth is off.");
355 return;
356 }
357 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
358 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
359
360 return pimpl->HidHostSendData(device, id, size, type);
361 }
362
HidHostSetReport(std::string device, uint8_t type, std::string &report)363 void HidHost::HidHostSetReport(std::string device, uint8_t type, std::string &report)
364 {
365 if (!IS_BT_ENABLED()) {
366 HILOGE("bluetooth is off.");
367 return;
368 }
369 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
370 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
371
372 return pimpl->HidHostSetReport(device, type, report);
373 }
374
HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)375 void HidHost::HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
376 {
377 if (!IS_BT_ENABLED()) {
378 HILOGE("bluetooth is off.");
379 return;
380 }
381 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
382 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
383
384 return pimpl->HidHostGetReport(device, id, size, type);
385 }
386 } // namespace Bluetooth
387 } // namespace OHOS