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