1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android/hardware/bluetooth/1.0/types.h>
18 #include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
19 #include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
20 #include <bluetooth/log.h>
21 
22 #include "common/stop_watch.h"
23 #include "hal/hci_backend.h"
24 #include "os/alarm.h"
25 #include "os/system_properties.h"
26 
27 using ::android::hardware::hidl_vec;
28 using ::android::hardware::Return;
29 using ::android::hardware::Void;
30 using bluetooth::common::BindOnce;
31 using bluetooth::os::Handler;
32 
33 using IBluetoothHci_1_0 = ::android::hardware::bluetooth::V1_0::IBluetoothHci;
34 using IBluetoothHci_1_1 = ::android::hardware::bluetooth::V1_1::IBluetoothHci;
35 using IBluetoothHciCallbacks_1_1 = ::android::hardware::bluetooth::V1_1::IBluetoothHciCallbacks;
36 
37 namespace bluetooth::hal {
38 
39 class HidlHciCallbacks : public IBluetoothHciCallbacks_1_1 {
40 public:
HidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks)41   HidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks) : callbacks_(callbacks) {}
42 
43   using HidlStatus = ::android::hardware::bluetooth::V1_0::Status;
initializationComplete(HidlStatus status)44   Return<void> initializationComplete(HidlStatus status) override {
45     log::assert_that(status == HidlStatus::SUCCESS, "status == HidlStatus::SUCCESS");
46     callbacks_->initializationComplete();
47     return Void();
48   }
49 
hciEventReceived(const hidl_vec<uint8_t> & packet)50   Return<void> hciEventReceived(const hidl_vec<uint8_t>& packet) override {
51     callbacks_->hciEventReceived(packet);
52     return Void();
53   }
54 
aclDataReceived(const hidl_vec<uint8_t> & packet)55   Return<void> aclDataReceived(const hidl_vec<uint8_t>& packet) override {
56     callbacks_->aclDataReceived(packet);
57     return Void();
58   }
59 
scoDataReceived(const hidl_vec<uint8_t> & data)60   Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) override {
61     callbacks_->scoDataReceived(data);
62     return Void();
63   }
64 
isoDataReceived(const hidl_vec<uint8_t> & data)65   Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
66     callbacks_->isoDataReceived(data);
67     return Void();
68   }
69 
70 private:
71   std::shared_ptr<HciBackendCallbacks> callbacks_;
72 };
73 
74 class HidlHci : public HciBackend {
75   class DeathRecipient : public ::android::hardware::hidl_death_recipient {
76   public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)77     virtual void serviceDied(uint64_t /*cookie*/,
78                              const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
79       log::error("The Bluetooth HAL service died. Dumping logs and crashing in 1 second.");
80       common::StopWatch::DumpStopWatchLog();
81       // At shutdown, sometimes the HAL service gets killed before Bluetooth.
82       std::this_thread::sleep_for(std::chrono::seconds(1));
83       log::fatal("The Bluetooth HAL died.");
84     }
85   };
86 
87 public:
HidlHci(Handler * module_handler)88   HidlHci(Handler* module_handler) {
89     log::info("Trying to find a HIDL interface");
90     const int32_t timeout_ms = get_adjusted_timeout(500);
91 
92     auto get_service_alarm = new os::Alarm(module_handler);
93     get_service_alarm->Schedule(
94             BindOnce(
95                     [](uint32_t timeout_ms) {
96                       const std::string kBoardProperty = "ro.product.board";
97                       const std::string kCuttlefishBoard = "cutf";
98                       auto board_name = os::GetSystemProperty(kBoardProperty);
99                       bool emulator =
100                               board_name.has_value() && board_name.value() == kCuttlefishBoard;
101                       if (emulator) {
102                         log::error("board_name: {}", board_name.value());
103                         log::error(
104                                 "Unable to get a Bluetooth service after {}ms, start "
105                                 "the HAL before starting "
106                                 "Bluetooth",
107                                 timeout_ms);
108                         return;
109                       }
110                       log::fatal(
111                               "Unable to get a Bluetooth service after {}ms, start "
112                               "the HAL before starting "
113                               "Bluetooth",
114                               timeout_ms);
115                     },
116                     timeout_ms),
117             std::chrono::milliseconds(timeout_ms));
118 
119     hci_1_1_ = IBluetoothHci_1_1::getService();
120     if (hci_1_1_) {
121       hci_ = hci_1_1_;
122     } else {
123       hci_ = IBluetoothHci_1_0::getService();
124     }
125 
126     get_service_alarm->Cancel();
127     delete get_service_alarm;
128 
129     log::assert_that(hci_ != nullptr, "assert failed: hci_ != nullptr");
130 
131     death_recipient_ = new DeathRecipient();
132     auto death_link = hci_->linkToDeath(death_recipient_, 0);
133     log::assert_that(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
134   }
135 
~HidlHci()136   ~HidlHci() {
137     log::assert_that(hci_ != nullptr, "assert failed: hci_ != nullptr");
138     auto death_unlink = hci_->unlinkToDeath(death_recipient_);
139     if (!death_unlink.isOk()) {
140       log::error("Error unlinking death recipient from the Bluetooth HAL");
141     }
142     auto close_status = hci_->close();
143     if (!close_status.isOk()) {
144       log::error("Error calling close on the Bluetooth HAL");
145     }
146     hci_ = nullptr;
147     hci_1_1_ = nullptr;
148   }
149 
initialize(std::shared_ptr<HciBackendCallbacks> callbacks)150   void initialize(std::shared_ptr<HciBackendCallbacks> callbacks) override {
151     hci_callbacks_ = new HidlHciCallbacks(callbacks);
152     if (hci_1_1_ != nullptr) {
153       hci_1_1_->initialize_1_1(hci_callbacks_);
154     } else {
155       hci_->initialize(hci_callbacks_);
156     }
157   }
158 
sendHciCommand(const std::vector<uint8_t> & command)159   void sendHciCommand(const std::vector<uint8_t>& command) override {
160     hci_->sendHciCommand(command);
161   }
162 
sendAclData(const std::vector<uint8_t> & packet)163   void sendAclData(const std::vector<uint8_t>& packet) override { hci_->sendAclData(packet); }
164 
sendScoData(const std::vector<uint8_t> & packet)165   void sendScoData(const std::vector<uint8_t>& packet) override { hci_->sendScoData(packet); }
166 
sendIsoData(const std::vector<uint8_t> & packet)167   void sendIsoData(const std::vector<uint8_t>& packet) override {
168     if (hci_1_1_ == nullptr) {
169       log::error("ISO is not supported in HAL v1.0");
170       return;
171     }
172     hci_1_1_->sendIsoData(packet);
173   }
174 
175 private:
get_adjusted_timeout(int32_t timeout)176   static int32_t get_adjusted_timeout(int32_t timeout) {
177     // Slower devices set this property.  While waiting longer for bluetooth
178     // is a poor user experience, it's not unexpected on these devices.
179     // At the same time, we don't get arbitrarily long to start up bluetooth.
180     // There are other, more concretely set timeouts which can get triggered,
181     // and having a timeout here helps narrow down the problematic area.
182     // As a pragmatic compromise, we cap this multiplier at 2.
183     const uint32_t multiplier = os::GetSystemPropertyUint32("ro.hw_timeout_multiplier", 1);
184     if (multiplier > 1) {
185       return timeout * 2;
186     }
187     return timeout;
188   }
189 
190   android::sp<DeathRecipient> death_recipient_;
191   android::sp<HidlHciCallbacks> hci_callbacks_;
192   android::sp<IBluetoothHci_1_0> hci_;
193   android::sp<IBluetoothHci_1_1> hci_1_1_;
194 };
195 
CreateHidl(Handler * handler)196 std::shared_ptr<HciBackend> HciBackend::CreateHidl(Handler* handler) {
197   return std::make_shared<HidlHci>(handler);
198 }
199 
200 }  // namespace bluetooth::hal
201