1 /*
2 * Copyright (C) 2023 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 std::shared_ptrecific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "lmp_event_hal_test"
18
19 #include <aidl/Gtest.h>
20 #include <aidl/Vintf.h>
21
22 #include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEvent.h>
23 #include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEventCallback.h>
24 #include <aidl/android/hardware/bluetooth/lmp_event/Direction.h>
25 #include <aidl/android/hardware/bluetooth/lmp_event/AddressType.h>
26 #include <aidl/android/hardware/bluetooth/lmp_event/LmpEventId.h>
27 #include <aidl/android/hardware/bluetooth/lmp_event/Timestamp.h>
28
29 #include <android/binder_auto_utils.h>
30 #include <android/binder_manager.h>
31 #include <binder/IServiceManager.h>
32 #include <binder/ProcessState.h>
33 #include <log/log.h>
34
35 #include <chrono>
36 #include <condition_variable>
37 #include <cinttypes>
38 #include <thread>
39
40 using ::aidl::android::hardware::bluetooth::lmp_event::BnBluetoothLmpEventCallback;
41 using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEvent;
42 using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEventCallback;
43 using ::aidl::android::hardware::bluetooth::lmp_event::Direction;
44 using ::aidl::android::hardware::bluetooth::lmp_event::AddressType;
45 using ::aidl::android::hardware::bluetooth::lmp_event::LmpEventId;
46 using ::aidl::android::hardware::bluetooth::lmp_event::Timestamp;
47
48 using ::android::ProcessState;
49 using ::ndk::SpAIBinder;
50
51 namespace {
52 static constexpr std::chrono::milliseconds kEventTimeoutMs(10000);
53 }
54
55 class BluetoothLmpEventTest : public testing::TestWithParam<std::string> {
56 public:
SetUp()57 virtual void SetUp() override {
58 ALOGI("%s", __func__);
59
60 ibt_lmp_event_ = IBluetoothLmpEvent::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
61 ASSERT_NE(ibt_lmp_event_, nullptr);
62
63 ibt_lmp_event_cb_ = ndk::SharedRefBase::make<BluetoothLmpEventCallback>(*this);
64 ASSERT_NE(ibt_lmp_event_cb_, nullptr);
65 }
66
TearDown()67 virtual void TearDown() override {
68 ALOGI("%s", __func__);
69 ibt_lmp_event_->unregisterLmpEvents(address_type, address);
70
71 ibt_lmp_event_cb_ = nullptr;
72 }
73
74 class BluetoothLmpEventCallback : public BnBluetoothLmpEventCallback {
75 public:
76 BluetoothLmpEventTest& parent_;
BluetoothLmpEventCallback(BluetoothLmpEventTest & parent)77 BluetoothLmpEventCallback(BluetoothLmpEventTest& parent)
78 : parent_(parent) {}
79 ~BluetoothLmpEventCallback() = default;
80
onEventGenerated(const Timestamp & timestamp,AddressType address_type,const std::array<uint8_t,6> & address,Direction direction,LmpEventId lmp_event_id,char16_t conn_event_counter)81 ::ndk::ScopedAStatus onEventGenerated(const Timestamp& timestamp, AddressType address_type,
82 const std::array<uint8_t, 6>& address, Direction direction,
83 LmpEventId lmp_event_id, char16_t conn_event_counter) override {
84 for (auto t: address) {
85 ALOGD("%s: 0x%02x", __func__, t);
86 }
87 if (direction == Direction::TX) {
88 ALOGD("%s: Transmitting", __func__);
89 } else if (direction == Direction::RX) {
90 ALOGD("%s: Receiving", __func__);
91 }
92 if (address_type == AddressType::PUBLIC) {
93 ALOGD("%s: Public address", __func__);
94 } else if (address_type == AddressType::RANDOM) {
95 ALOGD("%s: Random address", __func__);
96 }
97 if (lmp_event_id == LmpEventId::CONNECT_IND) {
98 ALOGD("%s: initiating connection", __func__);
99 } else if (lmp_event_id == LmpEventId::LL_PHY_UPDATE_IND) {
100 ALOGD("%s: PHY update indication", __func__);
101 }
102
103 ALOGD("%s: time: %" PRId64 "counter value: %x", __func__, timestamp.bluetoothTimeUs, conn_event_counter);
104
105 parent_.event_recv = true;
106 parent_.notify();
107
108 return ::ndk::ScopedAStatus::ok();
109 }
onRegistered(bool status)110 ::ndk::ScopedAStatus onRegistered(bool status) override {
111 ALOGD("%s: status: %d", __func__, status);
112 parent_.status_recv = status;
113 parent_.notify();
114 return ::ndk::ScopedAStatus::ok();
115 }
116 };
117
notify()118 inline void notify() {
119 std::unique_lock<std::mutex> lock(lmp_event_mtx);
120 lmp_event_cv.notify_one();
121 }
122
wait(bool is_register_event)123 inline void wait(bool is_register_event) {
124 std::unique_lock<std::mutex> lock(lmp_event_mtx);
125
126
127 if (is_register_event) {
128 lmp_event_cv.wait(lock, [&]() { return status_recv == true; });
129 } else {
130 lmp_event_cv.wait_for(lock, kEventTimeoutMs,
131 [&](){ return event_recv == true; });
132 }
133
134 }
135
136 std::shared_ptr<IBluetoothLmpEvent> ibt_lmp_event_;
137 std::shared_ptr<IBluetoothLmpEventCallback> ibt_lmp_event_cb_;
138
139 AddressType address_type;
140 std::array<uint8_t, 6> address;
141
142 std::atomic<bool> event_recv;
143 bool status_recv;
144
145 std::mutex lmp_event_mtx;
146 std::condition_variable lmp_event_cv;
147 };
148
TEST_P(BluetoothLmpEventTest,RegisterAndReceive)149 TEST_P(BluetoothLmpEventTest, RegisterAndReceive) {
150 address = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
151 address_type = AddressType::RANDOM;
152 std::vector<LmpEventId> lmp_event_ids{LmpEventId::CONNECT_IND, LmpEventId::LL_PHY_UPDATE_IND};
153
154 ibt_lmp_event_->registerForLmpEvents(ibt_lmp_event_cb_, address_type, address, lmp_event_ids);
155 wait(true);
156 EXPECT_EQ(true, status_recv);
157
158 /* Wait for event generated here */
159 wait(false);
160 EXPECT_EQ(true, event_recv);
161
162 ibt_lmp_event_->unregisterLmpEvents(address_type, address);
163 }
164
165 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothLmpEventTest);
166 INSTANTIATE_TEST_SUITE_P(BluetoothLmpEvent, BluetoothLmpEventTest,
167 testing::ValuesIn(android::getAidlHalInstanceNames(IBluetoothLmpEvent::descriptor)),
168 android::PrintInstanceNameToString);
169
main(int argc,char ** argv)170 int main(int argc, char** argv) {
171 ::testing::InitGoogleTest(&argc, argv);
172 ProcessState::self()->setThreadPoolMaxThreadCount(1);
173 ProcessState::self()->startThreadPool();
174 return RUN_ALL_TESTS();
175 }
176
177