• 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_log.h"
21 #include "bluetooth_observer_list.h"
22 #include "bluetooth_hid_host_observer_stub.h"
23 #include "bluetooth_utils.h"
24 #include "i_bluetooth_hid_host.h"
25 #include "i_bluetooth_host.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 
29 namespace OHOS {
30 namespace Bluetooth {
31 class HidHostInnerObserver : public BluetoothHidHostObserverStub {
32 public:
HidHostInnerObserver(BluetoothObserverList<HidHostObserver> & observers)33     explicit HidHostInnerObserver(BluetoothObserverList<HidHostObserver> &observers) : observers_(observers)
34     {
35         HILOGI("Enter!");
36     }
~HidHostInnerObserver()37     ~HidHostInnerObserver() override
38     {
39         HILOGI("Enter!");
40     }
41 
OnConnectionStateChanged(const BluetoothRawAddress & device,int32_t state)42     ErrCode OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state) override
43     {
44         HILOGI("hid conn state, device: %{public}s, state: %{public}s",
45             GetEncryptAddr((device).GetAddress()).c_str(), GetProfileConnStateName(state).c_str());
46         BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
47         observers_.ForEach([remoteDevice, state](std::shared_ptr<HidHostObserver> observer) {
48             observer->OnConnectionStateChanged(remoteDevice, state);
49         });
50         return NO_ERROR;
51     }
52 
53 private:
54     BluetoothObserverList<HidHostObserver> &observers_;
55     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(HidHostInnerObserver);
56 };
57 
58 struct HidHost::impl {
59     impl();
60     ~impl();
GetDevicesByStatesOHOS::Bluetooth::HidHost::impl61     int32_t GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice>& result)
62     {
63         HILOGI("Enter!");
64         if (!proxy_) {
65             HILOGE("proxy_ is nullptr.");
66             return BT_ERR_SERVICE_DISCONNECTED;
67         }
68         if (!IS_BT_ENABLED()) {
69             HILOGE("bluetooth is off.");
70             return BT_ERR_INVALID_STATE;
71         }
72 
73         std::vector<BluetoothRawAddress> rawDevices;
74         std::vector<int32_t> tmpStates;
75         for (int32_t state : states) {
76             tmpStates.push_back((int32_t)state);
77         }
78 
79         int32_t ret = proxy_->GetDevicesByStates(tmpStates, rawDevices);
80         if (ret != BT_SUCCESS) {
81             HILOGE("inner error.");
82             return ret;
83         }
84 
85         for (BluetoothRawAddress rawDevice : rawDevices) {
86             BluetoothRemoteDevice remoteDevice(rawDevice.GetAddress(), 1);
87             result.push_back(remoteDevice);
88         }
89 
90         return BT_SUCCESS;
91     }
92 
GetDeviceStateOHOS::Bluetooth::HidHost::impl93     int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
94     {
95         HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
96         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
97             HILOGE("invalid param.");
98             return BT_ERR_INVALID_PARAM;
99         }
100         if (!IS_BT_ENABLED()) {
101             HILOGE("bluetooth is off.");
102             return BT_ERR_INVALID_STATE;
103         }
104         return proxy_->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
105     }
106 
ConnectOHOS::Bluetooth::HidHost::impl107     int32_t Connect(const BluetoothRemoteDevice &device)
108     {
109         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
110             HILOGE("invalid param.");
111             return BT_ERR_INVALID_PARAM;
112         }
113         if (!IS_BT_ENABLED()) {
114             HILOGE("bluetooth is off.");
115             return BT_ERR_INVALID_STATE;
116         }
117 
118         int cod = 0;
119         int32_t err = device.GetDeviceClass(cod);
120         if (err != BT_SUCCESS) {
121             HILOGE("GetDeviceClass Failed.");
122             return false;
123         }
124         BluetoothDeviceClass devClass = BluetoothDeviceClass(cod);
125         if (!devClass.IsProfileSupported(BluetoothDevice::PROFILE_HID)) {
126             HILOGE("hid connect failed. The remote device does not support HID service.");
127             return BT_ERR_PROFILE_DISABLED;
128         }
129         cod = devClass.GetClassOfDevice();
130         HILOGI("hid connect remote device: %{public}s, cod: %{public}d", GET_ENCRYPT_ADDR(device), cod);
131         return proxy_->Connect(BluetoothRawAddress(device.GetDeviceAddr()));
132     }
133 
DisconnectOHOS::Bluetooth::HidHost::impl134     int32_t Disconnect(const BluetoothRemoteDevice &device)
135     {
136         HILOGI("hid disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
137         if (proxy_ == nullptr || !device.IsValidBluetoothRemoteDevice()) {
138             HILOGE("invalid param.");
139             return BT_ERR_INVALID_PARAM;
140         }
141         if (!IS_BT_ENABLED()) {
142             HILOGE("bluetooth is off.");
143             return BT_ERR_INVALID_STATE;
144         }
145         return proxy_->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
146     }
147 
RegisterObserverOHOS::Bluetooth::HidHost::impl148     void RegisterObserver(std::shared_ptr<HidHostObserver> observer)
149     {
150         HILOGI("Enter!");
151         observers_.Register(observer);
152     }
153 
DeregisterObserverOHOS::Bluetooth::HidHost::impl154     void DeregisterObserver(std::shared_ptr<HidHostObserver> observer)
155     {
156         HILOGI("Enter!");
157         observers_.Deregister(observer);
158     }
159 
HidHostVCUnplugOHOS::Bluetooth::HidHost::impl160     void HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
161     {
162         HILOGI("Enter!");
163         int result;
164         if (proxy_ != nullptr && IS_BT_ENABLED()) {
165             proxy_->HidHostVCUnplug(device, id, size, type, result);
166         }
167     }
168 
HidHostSendDataOHOS::Bluetooth::HidHost::impl169     void HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type)
170     {
171         HILOGI("Enter!");
172         int result;
173         if (proxy_ != nullptr && IS_BT_ENABLED()) {
174             proxy_->HidHostSendData(device, id, size, type, result);
175         }
176     }
177 
HidHostSetReportOHOS::Bluetooth::HidHost::impl178     void HidHostSetReport(std::string device, uint8_t type, uint16_t size, uint8_t report)
179     {
180         HILOGI("Enter!");
181         int result;
182         if (proxy_ != nullptr && IS_BT_ENABLED()) {
183             proxy_->HidHostSetReport(device, type, size, report, result);
184         }
185     }
186 
HidHostGetReportOHOS::Bluetooth::HidHost::impl187     void HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
188     {
189         HILOGI("Enter!");
190         int result;
191         if (proxy_ != nullptr && IS_BT_ENABLED()) {
192             proxy_->HidHostGetReport(device, id, size, type, result);
193         }
194     }
195 
196 private:
197     BluetoothObserverList<HidHostObserver> observers_;
198     sptr<HidHostInnerObserver> innerObserver_;
199     sptr<IBluetoothHidHost> proxy_;
200     class HidHostDeathRecipient;
201     sptr<HidHostDeathRecipient> deathRecipient_;
GetHidProxyOHOS::Bluetooth::HidHost::impl202     void GetHidProxy()
203     {
204         sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
205         if (samgr == nullptr) {
206             HILOGE("error: no samgr");
207             return;
208         }
209         sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
210         if (hostRemote == nullptr) {
211             HILOGE("failed: no hostRemote");
212             return;
213         }
214 
215         sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
216         if (hostProxy == nullptr) {
217             HILOGE("error: host no proxy");
218             return;
219         }
220 
221         sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_HID_HOST_SERVER);
222         if (remote == nullptr) {
223             HILOGE("failed: no remote");
224             return;
225         }
226 
227         proxy_ = iface_cast<IBluetoothHidHost>(remote);
228         if (proxy_ == nullptr) {
229             HILOGE("error: no proxy");
230             return;
231         }
232     }
233 };
234 
235 class HidHost::impl::HidHostDeathRecipient final : public IRemoteObject::DeathRecipient {
236 public:
HidHostDeathRecipient(HidHost::impl & impl)237     HidHostDeathRecipient(HidHost::impl &impl) : impl_(impl)
238     {};
239     ~HidHostDeathRecipient() final = default;
240     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(HidHostDeathRecipient);
241 
OnRemoteDied(const wptr<IRemoteObject> & remote)242     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
243     {
244         HILOGI("starts");
245         impl_.proxy_->AsObject()->RemoveDeathRecipient(impl_.deathRecipient_);
246         impl_.proxy_ = nullptr;
247 
248         // Re-obtain the proxy and register the observer.
249         sleep(GET_PROXY_SLEEP_SEC);
250         impl_.GetHidProxy();
251         if (impl_.proxy_ == nullptr) {
252             HILOGE("proxy reset failed");
253             return;
254         }
255         if (impl_.innerObserver_ == nullptr || impl_.deathRecipient_ == nullptr) {
256             HILOGE("innerObserver_ or deathRecipient_ is null");
257             return;
258         }
259         impl_.proxy_->RegisterObserver(impl_.innerObserver_);
260         impl_.proxy_->AsObject()->AddDeathRecipient(impl_.deathRecipient_);
261     }
262 
263 private:
264     HidHost::impl &impl_;
265 };
266 
impl()267 HidHost::impl::impl()
268 {
269     HILOGI("Enter!");
270     GetHidProxy();
271     if (proxy_ == nullptr) {
272         HILOGI("get proxy_ failed");
273         return;
274     }
275 
276     innerObserver_ = new HidHostInnerObserver(observers_);
277     if (innerObserver_ == nullptr) {
278         HILOGE("innerObserver_ is null");
279         return;
280     }
281     proxy_->RegisterObserver(innerObserver_);
282 
283     deathRecipient_ = new HidHostDeathRecipient(*this);
284     if (deathRecipient_ == nullptr) {
285         HILOGE("deathRecipient_ is null");
286         return;
287     }
288     proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
289 }
290 
~impl()291 HidHost::impl::~impl()
292 {
293     HILOGI("Enter!");
294     if (proxy_ != nullptr) {
295         proxy_->DeregisterObserver(innerObserver_);
296     }
297     proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
298 }
299 
HidHost()300 HidHost::HidHost()
301 {
302     pimpl = std::make_unique<impl>();
303 }
304 
~HidHost()305 HidHost::~HidHost()
306 {}
307 
GetProfile()308 HidHost *HidHost::GetProfile()
309 {
310     static HidHost instance;
311     return &instance;
312 }
313 
GetDevicesByStates(std::vector<int> states,std::vector<BluetoothRemoteDevice> & result)314 int32_t HidHost::GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)
315 {
316     return pimpl->GetDevicesByStates(states, result);
317 }
318 
GetDeviceState(const BluetoothRemoteDevice & device,int32_t & state)319 int32_t HidHost::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
320 {
321     return pimpl->GetDeviceState(device, state);
322 }
323 
Connect(const BluetoothRemoteDevice & device)324 int32_t HidHost::Connect(const BluetoothRemoteDevice &device)
325 {
326     return pimpl->Connect(device);
327 }
328 
Disconnect(const BluetoothRemoteDevice & device)329 int32_t HidHost::Disconnect(const BluetoothRemoteDevice &device)
330 {
331     return pimpl->Disconnect(device);
332 }
333 
RegisterObserver(HidHostObserver * observer)334 void HidHost::RegisterObserver(HidHostObserver *observer)
335 {
336     std::shared_ptr<HidHostObserver> observerPtr(observer, [](HidHostObserver *) {});
337     return pimpl->RegisterObserver(observerPtr);
338 }
339 
DeregisterObserver(HidHostObserver * observer)340 void HidHost::DeregisterObserver(HidHostObserver *observer)
341 {
342     std::shared_ptr<HidHostObserver> observerPtr(observer, [](HidHostObserver *) {});
343     return pimpl->DeregisterObserver(observerPtr);
344 }
345 
HidHostVCUnplug(std::string device,uint8_t id,uint16_t size,uint8_t type)346 void HidHost::HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type)
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     return pimpl->HidHostSendData(device, id, size, type);
354 }
355 
HidHostSetReport(std::string device,uint8_t type,uint16_t size,uint8_t report)356 void HidHost::HidHostSetReport(std::string device, uint8_t type, uint16_t size, uint8_t report)
357 {
358     return pimpl->HidHostSetReport(device, type, size, report);
359 }
360 
HidHostGetReport(std::string device,uint8_t id,uint16_t size,uint8_t type)361 void HidHost::HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type)
362 {
363     return pimpl->HidHostGetReport(device, id, size, type);
364 }
365 }  // namespace Bluetooth
366 }  // namespace OHOS