• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_load_system_ability.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         HILOGI("Enter!");
38     }
~HidHostInnerObserver()39     ~HidHostInnerObserver() override
40     {
41         HILOGI("Enter!");
42     }
43 
OnConnectionStateChanged(const BluetoothRawAddress & device,int32_t state)44     ErrCode OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state) override
45     {
46         HILOGD("hid conn state, device: %{public}s, state: %{public}s",
47             GetEncryptAddr((device).GetAddress()).c_str(), GetProfileConnStateName(state).c_str());
48         BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
49         observers_.ForEach([remoteDevice, state](std::shared_ptr<HidHostObserver> observer) {
50             observer->OnConnectionStateChanged(remoteDevice, state);
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     bool InitHidHostProxy(void);
64 
GetDevicesByStatesOHOS::Bluetooth::HidHost::impl65     int32_t GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice>& result)
66     {
67         HILOGI("Enter!");
68         std::vector<BluetoothRawAddress> rawDevices;
69         std::vector<int32_t> tmpStates;
70         for (int32_t state : states) {
71             tmpStates.push_back((int32_t)state);
72         }
73 
74         if (!proxy_) {
75             HILOGE("proxy_ is nullptr.");
76             return BT_ERR_SERVICE_DISCONNECTED;
77         }
78         int32_t ret = proxy_->GetDevicesByStates(tmpStates, rawDevices);
79         if (ret != BT_NO_ERROR) {
80             HILOGE("inner error.");
81             return ret;
82         }
83 
84         for (BluetoothRawAddress rawDevice : rawDevices) {
85             BluetoothRemoteDevice remoteDevice(rawDevice.GetAddress(), 1);
86             result.push_back(remoteDevice);
87         }
88 
89         return BT_NO_ERROR;
90     }
91 
GetDeviceStateOHOS::Bluetooth::HidHost::impl92     int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
93     {
94         HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
95         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
96             HILOGE("invalid param.");
97             return BT_ERR_INVALID_PARAM;
98         }
99 
100         return proxy_->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
101     }
102 
ConnectOHOS::Bluetooth::HidHost::impl103     int32_t Connect(const BluetoothRemoteDevice &device)
104     {
105         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
106             HILOGE("invalid param.");
107             return BT_ERR_INVALID_PARAM;
108         }
109 
110         int cod = 0;
111         int32_t err = device.GetDeviceClass(cod);
112         if (err != BT_NO_ERROR) {
113             HILOGE("GetDeviceClass Failed.");
114             return false;
115         }
116         BluetoothDeviceClass devClass = BluetoothDeviceClass(cod);
117         if (!devClass.IsProfileSupported(BluetoothDevice::PROFILE_HID)) {
118             HILOGE("hid connect failed. The remote device does not support HID service.");
119             return BT_ERR_PROFILE_DISABLED;
120         }
121         cod = devClass.GetClassOfDevice();
122         HILOGI("hid connect remote device: %{public}s, cod: %{public}d", GET_ENCRYPT_ADDR(device), cod);
123         return proxy_->Connect(BluetoothRawAddress(device.GetDeviceAddr()));
124     }
125 
DisconnectOHOS::Bluetooth::HidHost::impl126     int32_t Disconnect(const BluetoothRemoteDevice &device)
127     {
128         HILOGI("hid disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
129         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
130             HILOGE("invalid param.");
131             return BT_ERR_INVALID_PARAM;
132         }
133 
134         return proxy_->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
135     }
136 
RegisterObserverOHOS::Bluetooth::HidHost::impl137     void RegisterObserver(std::shared_ptr<HidHostObserver> observer)
138     {
139         HILOGI("Enter!");
140         observers_.Register(observer);
141     }
142 
DeregisterObserverOHOS::Bluetooth::HidHost::impl143     void DeregisterObserver(std::shared_ptr<HidHostObserver> observer)
144     {
145         HILOGI("Enter!");
146         observers_.Deregister(observer);
147     }
148 
HidHostVCUnplugOHOS::Bluetooth::HidHost::impl149     void HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
150     {
151         HILOGI("Enter!");
152         int result;
153         if (proxy_ != nullptr) {
154             proxy_->HidHostVCUnplug(device, id, size, type, result);
155         }
156     }
157 
HidHostSendDataOHOS::Bluetooth::HidHost::impl158     void HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)
159     {
160         HILOGI("Enter!");
161         int result;
162         if (proxy_ != nullptr) {
163             proxy_->HidHostSendData(device, id, size, type, result);
164         }
165     }
166 
HidHostSetReportOHOS::Bluetooth::HidHost::impl167     void HidHostSetReport(std::string device, uint8_t type, uint16_t size, uint8_t report)
168     {
169         HILOGI("Enter!");
170         int result;
171         if (proxy_ != nullptr) {
172             proxy_->HidHostSetReport(device, type, size, report, result);
173         }
174     }
175 
HidHostGetReportOHOS::Bluetooth::HidHost::impl176     void HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
177     {
178         HILOGI("Enter!");
179         int result;
180         if (proxy_ != nullptr && IS_BT_ENABLED()) {
181             proxy_->HidHostGetReport(device, id, size, type, result);
182         }
183     }
184 
SetConnectStrategyOHOS::Bluetooth::HidHost::impl185     int SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
186     {
187         HILOGI("enter");
188         return proxy_->SetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
189     }
190 
GetConnectStrategyOHOS::Bluetooth::HidHost::impl191     int GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
192     {
193         HILOGI("enter");
194         return proxy_->GetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
195     }
196 
197     sptr<IBluetoothHidHost> proxy_;
198 private:
199     BluetoothObserverList<HidHostObserver> observers_;
200     sptr<HidHostInnerObserver> innerObserver_;
201     class HidHostDeathRecipient;
202     sptr<HidHostDeathRecipient> deathRecipient_;
203 };
204 
205 class HidHost::impl::HidHostDeathRecipient final : public IRemoteObject::DeathRecipient {
206 public:
HidHostDeathRecipient(HidHost::impl & impl)207     explicit HidHostDeathRecipient(HidHost::impl &impl) : impl_(impl)
208     {};
209     ~HidHostDeathRecipient() final = default;
210     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(HidHostDeathRecipient);
211 
OnRemoteDied(const wptr<IRemoteObject> & remote)212     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
213     {
214         HILOGI("starts");
215         std::lock_guard<std::mutex> lock(g_hidProxyMutex);
216         if (!impl_.proxy_) {
217             return;
218         }
219         impl_.proxy_ = nullptr;
220     }
221 
222 private:
223     HidHost::impl &impl_;
224 };
225 
impl()226 HidHost::impl::impl()
227 {
228     if (proxy_) {
229         return;
230     }
231     BluetootLoadSystemAbility::GetInstance().RegisterNotifyMsg(PROFILE_ID_HID_HOST_SERVER);
232     if (!BluetootLoadSystemAbility::GetInstance().HasSubscribedBluetoothSystemAbility()) {
233         BluetootLoadSystemAbility::GetInstance().SubScribeBluetoothSystemAbility();
234         return;
235     }
236     InitHidHostProxy();
237 }
238 
~impl()239 HidHost::impl::~impl()
240 {
241     HILOGI("Enter!");
242     if (proxy_ != nullptr) {
243         proxy_->DeregisterObserver(innerObserver_);
244         proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
245     }
246 }
247 
InitHidHostProxy(void)248 bool HidHost::impl::InitHidHostProxy(void)
249 {
250     HILOGI("enter");
251     std::lock_guard<std::mutex> lock(g_hidProxyMutex);
252     if (proxy_) {
253         return true;
254     }
255     proxy_ = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER);
256     if (!proxy_) {
257         HILOGE("get HidHost proxy fail");
258         return false;
259     }
260 
261     innerObserver_ = new HidHostInnerObserver(observers_);
262     if (innerObserver_ != nullptr) {
263         proxy_->RegisterObserver(innerObserver_);
264     }
265 
266     deathRecipient_ = new HidHostDeathRecipient(*this);
267     if (deathRecipient_ != nullptr) {
268         proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
269     }
270     return true;
271 }
272 
HidHost()273 HidHost::HidHost()
274 {
275     pimpl = std::make_unique<impl>();
276 }
277 
~HidHost()278 HidHost::~HidHost() {}
279 
Init()280 void HidHost::Init()
281 {
282     if (!pimpl) {
283         HILOGE("fails: no pimpl");
284         return;
285     }
286     if (!pimpl->InitHidHostProxy()) {
287         HILOGE("HidHost proxy is nullptr");
288         return;
289     }
290 }
291 
GetProfile()292 HidHost *HidHost::GetProfile()
293 {
294     static HidHost instance;
295     return &instance;
296 }
297 
GetDevicesByStates(std::vector<int> states,std::vector<BluetoothRemoteDevice> & result)298 int32_t HidHost::GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)
299 {
300     if (!IS_BT_ENABLED()) {
301         HILOGE("bluetooth is off.");
302         return BT_ERR_INVALID_STATE;
303     }
304 
305     if (pimpl == nullptr || !pimpl->proxy_) {
306         HILOGE("pimpl or hidHost proxy is nullptr");
307         return BT_ERR_UNAVAILABLE_PROXY;
308     }
309 
310     return pimpl->GetDevicesByStates(states, result);
311 }
312 
GetDeviceState(const BluetoothRemoteDevice & device,int32_t & state)313 int32_t HidHost::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
314 {
315     if (!IS_BT_ENABLED()) {
316         HILOGE("bluetooth is off.");
317         return BT_ERR_INVALID_STATE;
318     }
319 
320     if (pimpl == nullptr || !pimpl->proxy_) {
321         HILOGE("pimpl or hidHost proxy is nullptr");
322         return BT_ERR_UNAVAILABLE_PROXY;
323     }
324 
325     return pimpl->GetDeviceState(device, state);
326 }
327 
Connect(const BluetoothRemoteDevice & device)328 int32_t HidHost::Connect(const BluetoothRemoteDevice &device)
329 {
330     if (!IS_BT_ENABLED()) {
331         HILOGE("bluetooth is off.");
332         return BT_ERR_INVALID_STATE;
333     }
334 
335     if (pimpl == nullptr || !pimpl->proxy_) {
336         HILOGE("pimpl or hidHost proxy is nullptr");
337         return BT_ERR_UNAVAILABLE_PROXY;
338     }
339 
340     return pimpl->Connect(device);
341 }
342 
Disconnect(const BluetoothRemoteDevice & device)343 int32_t HidHost::Disconnect(const BluetoothRemoteDevice &device)
344 {
345     if (!IS_BT_ENABLED()) {
346         HILOGE("bluetooth is off.");
347         return BT_ERR_INVALID_STATE;
348     }
349 
350     if (pimpl == nullptr || !pimpl->proxy_) {
351         HILOGE("pimpl or hidHost proxy is nullptr");
352         return BT_ERR_UNAVAILABLE_PROXY;
353     }
354 
355     return pimpl->Disconnect(device);
356 }
357 
SetConnectStrategy(const BluetoothRemoteDevice & device,int strategy)358 int HidHost::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
359 {
360     HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
361     if (!IS_BT_ENABLED()) {
362         HILOGE("bluetooth is off.");
363         return BT_ERR_INVALID_STATE;
364     }
365 
366     if (pimpl == nullptr || !pimpl->proxy_) {
367         HILOGE("pimpl or hidHost proxy is nullptr");
368         return BT_ERR_UNAVAILABLE_PROXY;
369     }
370 
371     if ((!device.IsValidBluetoothRemoteDevice()) || (
372         (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
373         (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
374         HILOGI("input parameter error.");
375         return BT_ERR_INVALID_PARAM;
376     }
377     return pimpl->SetConnectStrategy(device, strategy);
378 }
379 
GetConnectStrategy(const BluetoothRemoteDevice & device,int & strategy) const380 int HidHost::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
381 {
382     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
383     if (!IS_BT_ENABLED()) {
384         HILOGE("bluetooth is off.");
385         return BT_ERR_INVALID_STATE;
386     }
387 
388     if (pimpl == nullptr || !pimpl->proxy_) {
389         HILOGE("pimpl or hidHost proxy is nullptr");
390         return BT_ERR_UNAVAILABLE_PROXY;
391     }
392 
393     if (!device.IsValidBluetoothRemoteDevice()) {
394         HILOGI("input parameter error.");
395         return BT_ERR_INVALID_PARAM;
396     }
397     return pimpl->GetConnectStrategy(device, strategy);
398 }
399 
RegisterObserver(HidHostObserver * observer)400 void HidHost::RegisterObserver(HidHostObserver *observer)
401 {
402     std::shared_ptr<HidHostObserver> observerPtr(observer, [](HidHostObserver *) {});
403     return pimpl->RegisterObserver(observerPtr);
404 }
405 
DeregisterObserver(HidHostObserver * observer)406 void HidHost::DeregisterObserver(HidHostObserver *observer)
407 {
408     std::shared_ptr<HidHostObserver> observerPtr(observer, [](HidHostObserver *) {});
409     return pimpl->DeregisterObserver(observerPtr);
410 }
411 
HidHostVCUnplug(std::string device,uint8_t id,uint16_t size,uint8_t type)412 void HidHost::HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
413 {
414     if (!IS_BT_ENABLED()) {
415         HILOGE("bluetooth is off.");
416         return;
417     }
418 
419     if (pimpl == nullptr || !pimpl->proxy_) {
420         HILOGE("pimpl or hidHost proxy is nullptr");
421         return;
422     }
423 
424     return pimpl->HidHostVCUnplug(device, id, size, type);
425 }
426 
HidHostSendData(std::string device,uint8_t id,uint16_t size,uint8_t type)427 void HidHost::HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)
428 {
429     if (!IS_BT_ENABLED()) {
430         HILOGE("bluetooth is off.");
431         return;
432     }
433 
434     if (pimpl == nullptr || !pimpl->proxy_) {
435         HILOGE("pimpl or hidHost proxy is nullptr");
436         return;
437     }
438 
439     return pimpl->HidHostSendData(device, id, size, type);
440 }
441 
HidHostSetReport(std::string device,uint8_t type,uint16_t size,uint8_t report)442 void HidHost::HidHostSetReport(std::string device, uint8_t type, uint16_t size, uint8_t report)
443 {
444     if (!IS_BT_ENABLED()) {
445         HILOGE("bluetooth is off.");
446         return;
447     }
448 
449     if (pimpl == nullptr || !pimpl->proxy_) {
450         HILOGE("pimpl or hidHost proxy is nullptr");
451         return;
452     }
453 
454     return pimpl->HidHostSetReport(device, type, size, report);
455 }
456 
HidHostGetReport(std::string device,uint8_t id,uint16_t size,uint8_t type)457 void HidHost::HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
458 {
459     if (!IS_BT_ENABLED()) {
460         HILOGE("bluetooth is off.");
461         return;
462     }
463 
464     if (pimpl == nullptr || !pimpl->proxy_) {
465         HILOGE("pimpl or hidHost proxy is nullptr");
466         return;
467     }
468 
469     return pimpl->HidHostGetReport(device, id, size, type);
470 }
471 } // namespace Bluetooth
472 } // namespace OHOS