1 /*
2 * Copyright (C) 2021 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 #include <aidl/Gtest.h>
17 #include <aidl/Vintf.h>
18 #include <aidl/android/hardware/uwb/BnUwbClientCallback.h>
19 #include <aidl/android/hardware/uwb/IUwb.h>
20 #include <aidl/android/hardware/uwb/IUwbChip.h>
21 #include <aidl/android/hardware/uwb/IUwbClientCallback.h>
22 #include <android/binder_auto_utils.h>
23 #include <android/binder_manager.h>
24 #include <binder/IServiceManager.h>
25 #include <binder/ProcessState.h>
26
27 #include <future>
28
29 using aidl::android::hardware::uwb::BnUwbClientCallback;
30 using aidl::android::hardware::uwb::IUwb;
31 using aidl::android::hardware::uwb::IUwbChip;
32 using aidl::android::hardware::uwb::IUwbClientCallback;
33 using aidl::android::hardware::uwb::UwbEvent;
34 using aidl::android::hardware::uwb::UwbStatus;
35 using android::ProcessState;
36 using android::String16;
37 using ndk::ScopedAStatus;
38 using ndk::SpAIBinder;
39
40 namespace {
41 constexpr static int kCallbackTimeoutMs = 250;
42 } // namespace
43
44 class UwbClientCallback : public BnUwbClientCallback {
45 public:
UwbClientCallback(const std::function<void (const std::vector<uint8_t> &)> & on_uci_message_cb,const std::function<void (UwbEvent,UwbStatus)> & on_hal_event_cb)46 UwbClientCallback(const std::function<void(const std::vector<uint8_t>&)>& on_uci_message_cb,
47 const std::function<void(UwbEvent, UwbStatus)>& on_hal_event_cb)
48 : on_uci_message_cb_(on_uci_message_cb), on_hal_event_cb_(on_hal_event_cb) {}
49
onUciMessage(const std::vector<uint8_t> & data)50 ScopedAStatus onUciMessage(const std::vector<uint8_t>& data) override {
51 on_uci_message_cb_(data);
52 return ScopedAStatus::ok();
53 }
54
onHalEvent(UwbEvent uwb_event,UwbStatus uwb_status)55 ScopedAStatus onHalEvent(UwbEvent uwb_event, UwbStatus uwb_status) override {
56 on_hal_event_cb_(uwb_event, uwb_status);
57 return ScopedAStatus::ok();
58 }
59
60 private:
61 std::function<void(const std::vector<uint8_t>&)> on_uci_message_cb_;
62 std::function<void(UwbEvent, UwbStatus)> on_hal_event_cb_;
63 };
64
65 class UwbAidl : public testing::TestWithParam<std::string> {
66 public:
SetUp()67 virtual void SetUp() override {
68 iuwb_ = IUwb::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
69 ASSERT_NE(iuwb_, nullptr);
70 }
TearDown()71 virtual void TearDown() override {
72 // Trigger HAL close at end of each test.
73 const auto iuwb_chip = getAnyChip();
74 iuwb_chip->close();
75 }
76 std::shared_ptr<IUwb> iuwb_;
77
78 // TODO (b/197638976): We pick the first chip here. Need to fix this
79 // for supporting multiple chips in the future.
getAnyChipName()80 std::string getAnyChipName() {
81 std::vector<std::string> chip_names;
82 ScopedAStatus status = iuwb_->getChips(&chip_names);
83 EXPECT_TRUE(status.isOk());
84 EXPECT_FALSE(chip_names.empty());
85 return chip_names[0];
86 }
87
88 // TODO (b/197638976): We pick the first chip here. Need to fix this
89 // for supporting multiple chips in the future.
getAnyChip()90 std::shared_ptr<IUwbChip> getAnyChip() {
91 std::shared_ptr<IUwbChip> iuwb_chip;
92 ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip);
93 EXPECT_TRUE(status.isOk());
94 EXPECT_NE(iuwb_chip, nullptr);
95 return iuwb_chip;
96 }
97
getAnyChipAndOpen()98 std::shared_ptr<IUwbChip> getAnyChipAndOpen() {
99 std::promise<void> open_cb_promise;
100 std::future<void> open_cb_future{open_cb_promise.get_future()};
101 std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
102 [](auto /* data */) {},
103 [&open_cb_promise](auto event, auto /* status */) {
104 if (event == UwbEvent::OPEN_CPLT) {
105 open_cb_promise.set_value();
106 }
107 });
108 std::chrono::milliseconds timeout{kCallbackTimeoutMs};
109 const auto iuwb_chip = getAnyChip();
110 EXPECT_TRUE(iuwb_chip->open(callback).isOk());
111 EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
112 return iuwb_chip;
113 }
114 };
115
TEST_P(UwbAidl,GetChips)116 TEST_P(UwbAidl, GetChips) {
117 std::vector<std::string> chip_names;
118 ScopedAStatus status = iuwb_->getChips(&chip_names);
119 EXPECT_TRUE(status.isOk());
120 EXPECT_FALSE(chip_names.empty());
121 }
122
TEST_P(UwbAidl,GetChip)123 TEST_P(UwbAidl, GetChip) {
124 std::shared_ptr<IUwbChip> iuwb_chip;
125 ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip);
126 EXPECT_TRUE(status.isOk());
127 EXPECT_NE(iuwb_chip, nullptr);
128 }
129
TEST_P(UwbAidl,ChipOpen)130 TEST_P(UwbAidl, ChipOpen) {
131 std::promise<void> open_cb_promise;
132 std::future<void> open_cb_future{open_cb_promise.get_future()};
133 std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
134 [](auto /* data */) {},
135 [&open_cb_promise](auto event, auto /* status */) {
136 if (event == UwbEvent::OPEN_CPLT) {
137 open_cb_promise.set_value();
138 }
139 });
140 std::chrono::milliseconds timeout{kCallbackTimeoutMs};
141 const auto iuwb_chip = getAnyChip();
142 EXPECT_TRUE(iuwb_chip->open(callback).isOk());
143 EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
144 }
145
TEST_P(UwbAidl,ChipClose)146 TEST_P(UwbAidl, ChipClose) {
147 std::promise<void> open_cb_promise;
148 std::future<void> open_cb_future{open_cb_promise.get_future()};
149 std::promise<void> close_cb_promise;
150 std::future<void> close_cb_future{close_cb_promise.get_future()};
151 std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
152 [](auto /* data */) {},
153 [&open_cb_promise, &close_cb_promise](auto event, auto /* status */) {
154 if (event == UwbEvent::OPEN_CPLT) {
155 open_cb_promise.set_value();
156 }
157 if (event == UwbEvent::CLOSE_CPLT) {
158 close_cb_promise.set_value();
159 }
160 });
161 std::chrono::milliseconds timeout{kCallbackTimeoutMs};
162 const auto iuwb_chip = getAnyChip();
163 EXPECT_TRUE(iuwb_chip->open(callback).isOk());
164 EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
165 EXPECT_TRUE(iuwb_chip->close().isOk());
166 EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
167 }
168
TEST_P(UwbAidl,ChipCoreInit)169 TEST_P(UwbAidl, ChipCoreInit) {
170 const auto iuwb_chip = getAnyChipAndOpen();
171 EXPECT_TRUE(iuwb_chip->coreInit().isOk());
172 }
173
TEST_P(UwbAidl,ChipSessionInit)174 TEST_P(UwbAidl, ChipSessionInit) {
175 const auto iuwb_chip = getAnyChipAndOpen();
176 EXPECT_TRUE(iuwb_chip->sessionInit(0).isOk());
177 }
178
TEST_P(UwbAidl,ChipGetSupportedAndroidUciVersion)179 TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
180 const auto iuwb_chip = getAnyChipAndOpen();
181 EXPECT_TRUE(iuwb_chip->coreInit().isOk());
182
183 int32_t version;
184 EXPECT_TRUE(iuwb_chip->getSupportedAndroidUciVersion(&version).isOk());
185 EXPECT_GT(version, 0);
186 }
187
TEST_P(UwbAidl,ChipGetName)188 TEST_P(UwbAidl, ChipGetName) {
189 std::string chip_name = getAnyChipName();
190 std::shared_ptr<IUwbChip> iuwb_chip;
191 ScopedAStatus status = iuwb_->getChip(chip_name, &iuwb_chip);
192 EXPECT_TRUE(status.isOk());
193 EXPECT_NE(iuwb_chip, nullptr);
194
195 std::string retrieved_chip_name;
196 status = iuwb_chip->getName(&retrieved_chip_name);
197 EXPECT_TRUE(status.isOk());
198 EXPECT_EQ(retrieved_chip_name, chip_name);
199 }
200
201 /**
202 TEST_P(UwbAidl, ChipSendUciMessage_GetDeviceInfo) {
203 const auto iuwb_chip = getAnyChipAndOpen(callback);
204 EXPECT_TRUE(iuwb_chip->coreInit(callback).isOk());
205
206 const std::vector<uint8_t>
207 EXPECT_TRUE(iuwb_chip->sendUciMessage().isOk());
208 } */
209
210 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UwbAidl);
211 INSTANTIATE_TEST_SUITE_P(Uwb, UwbAidl,
212 testing::ValuesIn(android::getAidlHalInstanceNames(IUwb::descriptor)),
213 android::PrintInstanceNameToString);
214
main(int argc,char ** argv)215 int main(int argc, char** argv) {
216 ::testing::InitGoogleTest(&argc, argv);
217 ProcessState::self()->setThreadPoolMaxThreadCount(1);
218 ProcessState::self()->startThreadPool();
219 return RUN_ALL_TESTS();
220 }
221