blob: b75a56f039991ce4ebbf4e837ef10d39ddeb4bed [file] [log] [blame]
ChengYou Ho10f8a482021-01-02 22:45:32 +08001/*
2 * Copyright (C) 2020 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#include <aidl/Gtest.h>
17#include <aidl/Vintf.h>
18
19#include <aidl/android/hardware/weaver/IWeaver.h>
20#include <android/binder_manager.h>
21#include <android/binder_process.h>
Eric Biggersb59654f2023-07-18 02:33:59 +000022#include <android/hardware/weaver/1.0/IWeaver.h>
23#include <hidl/GtestPrinter.h>
24#include <hidl/ServiceManagement.h>
ChengYou Ho10f8a482021-01-02 22:45:32 +080025
26#include <limits>
27
28using ::aidl::android::hardware::weaver::IWeaver;
29using ::aidl::android::hardware::weaver::WeaverConfig;
30using ::aidl::android::hardware::weaver::WeaverReadResponse;
ChengYou Ho20c47b42022-11-30 17:51:17 +000031using ::aidl::android::hardware::weaver::WeaverReadStatus;
ChengYou Ho10f8a482021-01-02 22:45:32 +080032
Eric Biggersb59654f2023-07-18 02:33:59 +000033using HidlIWeaver = ::android::hardware::weaver::V1_0::IWeaver;
34using HidlWeaverConfig = ::android::hardware::weaver::V1_0::WeaverConfig;
35using HidlWeaverReadStatus = ::android::hardware::weaver::V1_0::WeaverReadStatus;
36using HidlWeaverReadResponse = ::android::hardware::weaver::V1_0::WeaverReadResponse;
37using HidlWeaverStatus = ::android::hardware::weaver::V1_0::WeaverStatus;
ChengYou Ho10f8a482021-01-02 22:45:32 +080038
39const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
40const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
41const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
42const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
43
Eric Biggersb59654f2023-07-18 02:33:59 +000044class WeaverAdapter {
45 public:
46 virtual ~WeaverAdapter() {}
47 virtual bool isReady() = 0;
48 virtual ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) = 0;
49 virtual ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
50 WeaverReadResponse* _aidl_return) = 0;
51 virtual ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
52 const std::vector<uint8_t>& in_value) = 0;
53};
54
55class WeaverAidlAdapter : public WeaverAdapter {
56 public:
57 WeaverAidlAdapter(const std::string& param)
58 : aidl_weaver_(IWeaver::fromBinder(
59 ::ndk::SpAIBinder(AServiceManager_waitForService(param.c_str())))) {}
60 ~WeaverAidlAdapter() {}
61
62 bool isReady() { return aidl_weaver_ != nullptr; }
63
64 ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) {
65 return aidl_weaver_->getConfig(_aidl_return);
ChengYou Ho10f8a482021-01-02 22:45:32 +080066 }
67
Eric Biggersb59654f2023-07-18 02:33:59 +000068 ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
69 WeaverReadResponse* _aidl_return) {
70 return aidl_weaver_->read(in_slotId, in_key, _aidl_return);
71 }
ChengYou Ho10f8a482021-01-02 22:45:32 +080072
Eric Biggersb59654f2023-07-18 02:33:59 +000073 ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
74 const std::vector<uint8_t>& in_value) {
75 return aidl_weaver_->write(in_slotId, in_key, in_value);
76 }
77
78 private:
79 std::shared_ptr<IWeaver> aidl_weaver_;
ChengYou Ho10f8a482021-01-02 22:45:32 +080080};
81
Eric Biggersb59654f2023-07-18 02:33:59 +000082class WeaverHidlAdapter : public WeaverAdapter {
83 public:
84 WeaverHidlAdapter(const std::string& param) : hidl_weaver_(HidlIWeaver::getService(param)) {}
85 ~WeaverHidlAdapter() {}
86
87 bool isReady() { return hidl_weaver_ != nullptr; }
88
89 ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) {
90 bool callbackCalled = false;
91 HidlWeaverStatus status;
92 HidlWeaverConfig config;
93 auto ret = hidl_weaver_->getConfig([&](HidlWeaverStatus s, HidlWeaverConfig c) {
94 callbackCalled = true;
95 status = s;
96 config = c;
97 });
98 if (!ret.isOk() || !callbackCalled || status != HidlWeaverStatus::OK) {
99 return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
100 }
101 _aidl_return->slots = config.slots;
102 _aidl_return->keySize = config.keySize;
103 _aidl_return->valueSize = config.valueSize;
104 return ::ndk::ScopedAStatus::ok();
105 }
106
107 ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
108 WeaverReadResponse* _aidl_return) {
109 bool callbackCalled = false;
110 HidlWeaverReadStatus status;
111 std::vector<uint8_t> value;
112 uint32_t timeout;
113 auto ret = hidl_weaver_->read(in_slotId, in_key,
114 [&](HidlWeaverReadStatus s, HidlWeaverReadResponse r) {
115 callbackCalled = true;
116 status = s;
117 value = r.value;
118 timeout = r.timeout;
119 });
120 if (!ret.isOk() || !callbackCalled) {
121 return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
122 }
123 switch (status) {
124 case HidlWeaverReadStatus::OK:
125 _aidl_return->status = WeaverReadStatus::OK;
126 break;
127 case HidlWeaverReadStatus::FAILED:
128 _aidl_return->status = WeaverReadStatus::FAILED;
129 break;
130 case HidlWeaverReadStatus::INCORRECT_KEY:
131 _aidl_return->status = WeaverReadStatus::INCORRECT_KEY;
132 break;
133 case HidlWeaverReadStatus::THROTTLE:
134 _aidl_return->status = WeaverReadStatus::THROTTLE;
135 break;
136 default:
137 ADD_FAILURE() << "Unknown HIDL read status: " << static_cast<uint32_t>(status);
138 _aidl_return->status = WeaverReadStatus::FAILED;
139 break;
140 }
141 _aidl_return->value = value;
142 _aidl_return->timeout = timeout;
143 return ::ndk::ScopedAStatus::ok();
144 }
145
146 ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
147 const std::vector<uint8_t>& in_value) {
148 auto status = hidl_weaver_->write(in_slotId, in_key, in_value);
149 switch (status) {
150 case HidlWeaverStatus::OK:
151 return ::ndk::ScopedAStatus::ok();
152 case HidlWeaverStatus::FAILED:
153 return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
154 default:
155 ADD_FAILURE() << "Unknown HIDL write status: " << status.description();
156 return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
157 }
158 }
159
160 private:
161 android::sp<HidlIWeaver> hidl_weaver_;
162};
163
164class WeaverTest : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
165 protected:
166 void SetUp() override;
167 void TearDown() override {}
168
169 std::unique_ptr<WeaverAdapter> weaver;
170};
171
172void WeaverTest::SetUp() {
173 std::string api, instance_name;
174 std::tie(api, instance_name) = GetParam();
175 if (api == "hidl") {
176 weaver.reset(new WeaverHidlAdapter(instance_name));
177 } else if (api == "aidl") {
178 weaver.reset(new WeaverAidlAdapter(instance_name));
179 } else {
180 FAIL() << "Bad test parameterization";
181 }
182 ASSERT_TRUE(weaver->isReady());
183}
184
ChengYou Ho10f8a482021-01-02 22:45:32 +0800185/*
186 * Checks config values are suitably large
187 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000188TEST_P(WeaverTest, GetConfig) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800189 WeaverConfig config;
190
191 auto ret = weaver->getConfig(&config);
192
193 ASSERT_TRUE(ret.isOk());
194
195 EXPECT_GE(config.slots, 16u);
196 EXPECT_GE(config.keySize, 16u);
197 EXPECT_GE(config.valueSize, 16u);
198}
199
200/*
201 * Gets the config twice and checks they are the same
202 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000203TEST_P(WeaverTest, GettingConfigMultipleTimesGivesSameResult) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800204 WeaverConfig config1;
205 WeaverConfig config2;
206
207 auto ret = weaver->getConfig(&config1);
208 ASSERT_TRUE(ret.isOk());
209
210 ret = weaver->getConfig(&config2);
211 ASSERT_TRUE(ret.isOk());
212
213 EXPECT_EQ(config1, config2);
214}
215
216/*
217 * Gets the number of slots from the config and writes a key and value to the last one
218 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000219TEST_P(WeaverTest, WriteToLastSlot) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800220 WeaverConfig config;
221 const auto configRet = weaver->getConfig(&config);
222
223 ASSERT_TRUE(configRet.isOk());
224
225 const uint32_t lastSlot = config.slots - 1;
226 const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
227 ASSERT_TRUE(writeRet.isOk());
228}
229
230/*
231 * Writes a key and value to a slot
232 * Reads the slot with the same key and receives the value that was previously written
233 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000234TEST_P(WeaverTest, WriteFollowedByReadGivesTheSameValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800235 constexpr uint32_t slotId = 0;
236 const auto ret = weaver->write(slotId, KEY, VALUE);
237 ASSERT_TRUE(ret.isOk());
238
239 WeaverReadResponse response;
240 std::vector<uint8_t> readValue;
241 uint32_t timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000242 WeaverReadStatus status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800243 const auto readRet = weaver->read(slotId, KEY, &response);
244
245 readValue = response.value;
246 timeout = response.timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000247 status = response.status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800248
249 ASSERT_TRUE(readRet.isOk());
250 EXPECT_EQ(readValue, VALUE);
251 EXPECT_EQ(timeout, 0u);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000252 EXPECT_EQ(status, WeaverReadStatus::OK);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800253}
254
255/*
256 * Writes a key and value to a slot
257 * Overwrites the slot with a new key and value
258 * Reads the slot with the new key and receives the new value
259 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000260TEST_P(WeaverTest, OverwritingSlotUpdatesTheValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800261 constexpr uint32_t slotId = 0;
262 const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
263 ASSERT_TRUE(initialWriteRet.isOk());
264
265 const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
266 ASSERT_TRUE(overwriteRet.isOk());
267
268 WeaverReadResponse response;
269 std::vector<uint8_t> readValue;
270 uint32_t timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000271 WeaverReadStatus status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800272 const auto readRet = weaver->read(slotId, KEY, &response);
273
274 readValue = response.value;
275 timeout = response.timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000276 status = response.status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800277
278 ASSERT_TRUE(readRet.isOk());
279 EXPECT_EQ(readValue, OTHER_VALUE);
280 EXPECT_EQ(timeout, 0u);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000281 EXPECT_EQ(status, WeaverReadStatus::OK);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800282}
283
284/*
285 * Writes a key and value to a slot
286 * Reads the slot with a different key so does not receive the value
287 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000288TEST_P(WeaverTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800289 constexpr uint32_t slotId = 0;
290 const auto ret = weaver->write(slotId, KEY, VALUE);
291 ASSERT_TRUE(ret.isOk());
292
293 WeaverReadResponse response;
294 std::vector<uint8_t> readValue;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000295 WeaverReadStatus status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800296 const auto readRet =
297 weaver->read(slotId, WRONG_KEY, &response);
298
299 readValue = response.value;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000300 status = response.status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800301
ChengYou Ho20c47b42022-11-30 17:51:17 +0000302 ASSERT_TRUE(readRet.isOk());
ChengYou Ho10f8a482021-01-02 22:45:32 +0800303 EXPECT_TRUE(readValue.empty());
ChengYou Ho20c47b42022-11-30 17:51:17 +0000304 EXPECT_EQ(status, WeaverReadStatus::INCORRECT_KEY);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800305}
306
307/*
308 * Writing to an invalid slot fails
309 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000310TEST_P(WeaverTest, WritingToInvalidSlotFails) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800311 WeaverConfig config;
312 const auto configRet = weaver->getConfig(&config);
313 ASSERT_TRUE(configRet.isOk());
314
315 if (config.slots == std::numeric_limits<uint32_t>::max()) {
316 // If there are no invalid slots then pass
317 return;
318 }
319
320 const auto writeRet = weaver->write(config.slots, KEY, VALUE);
321 ASSERT_FALSE(writeRet.isOk());
322}
323
324/*
325 * Reading from an invalid slot fails rather than incorrect key
326 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000327TEST_P(WeaverTest, ReadingFromInvalidSlotFails) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800328 WeaverConfig config;
329 const auto configRet = weaver->getConfig(&config);
330 ASSERT_TRUE(configRet.isOk());
331
332 if (config.slots == std::numeric_limits<uint32_t>::max()) {
333 // If there are no invalid slots then pass
334 return;
335 }
336
337 WeaverReadResponse response;
338 std::vector<uint8_t> readValue;
339 uint32_t timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000340 WeaverReadStatus status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800341 const auto readRet =
342 weaver->read(config.slots, KEY, &response);
343
344 readValue = response.value;
345 timeout = response.timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000346 status = response.status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800347
ChengYou Ho20c47b42022-11-30 17:51:17 +0000348 ASSERT_TRUE(readRet.isOk());
ChengYou Ho10f8a482021-01-02 22:45:32 +0800349 EXPECT_TRUE(readValue.empty());
350 EXPECT_EQ(timeout, 0u);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000351 EXPECT_EQ(status, WeaverReadStatus::FAILED);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800352}
353
354/*
355 * Writing a key that is too large fails
356 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000357TEST_P(WeaverTest, WriteWithTooLargeKeyFails) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800358 WeaverConfig config;
359 const auto configRet = weaver->getConfig(&config);
360 ASSERT_TRUE(configRet.isOk());
361
362 std::vector<uint8_t> bigKey(config.keySize + 1);
363
364 constexpr uint32_t slotId = 0;
365 const auto writeRet = weaver->write(slotId, bigKey, VALUE);
366 ASSERT_FALSE(writeRet.isOk());
367}
368
369/*
370 * Writing a value that is too large fails
371 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000372TEST_P(WeaverTest, WriteWithTooLargeValueFails) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800373 WeaverConfig config;
374 const auto configRet = weaver->getConfig(&config);
375 ASSERT_TRUE(configRet.isOk());
376
377 std::vector<uint8_t> bigValue(config.valueSize + 1);
378
379 constexpr uint32_t slotId = 0;
380 const auto writeRet = weaver->write(slotId, KEY, bigValue);
381 ASSERT_FALSE(writeRet.isOk());
382}
383
384/*
385 * Reading with a key that is loo large fails
386 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000387TEST_P(WeaverTest, ReadWithTooLargeKeyFails) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800388 WeaverConfig config;
389 const auto configRet = weaver->getConfig(&config);
390 ASSERT_TRUE(configRet.isOk());
391
392 std::vector<uint8_t> bigKey(config.keySize + 1);
393
394 constexpr uint32_t slotId = 0;
395 WeaverReadResponse response;
396 std::vector<uint8_t> readValue;
397 uint32_t timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000398 WeaverReadStatus status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800399 const auto readRet =
400 weaver->read(slotId, bigKey, &response);
401
402 readValue = response.value;
403 timeout = response.timeout;
ChengYou Ho20c47b42022-11-30 17:51:17 +0000404 status = response.status;
ChengYou Ho10f8a482021-01-02 22:45:32 +0800405
ChengYou Ho20c47b42022-11-30 17:51:17 +0000406 ASSERT_TRUE(readRet.isOk());
ChengYou Ho10f8a482021-01-02 22:45:32 +0800407 EXPECT_TRUE(readValue.empty());
408 EXPECT_EQ(timeout, 0u);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000409 EXPECT_EQ(status, WeaverReadStatus::FAILED);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800410}
411
Eric Biggersb59654f2023-07-18 02:33:59 +0000412// Instantiate the test for each HIDL Weaver service.
ChengYou Ho10f8a482021-01-02 22:45:32 +0800413INSTANTIATE_TEST_SUITE_P(
Eric Biggersb59654f2023-07-18 02:33:59 +0000414 PerHidlInstance, WeaverTest,
415 testing::Combine(testing::Values("hidl"),
416 testing::ValuesIn(android::hardware::getAllHalInstanceNames(
417 HidlIWeaver::descriptor))),
418 [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
419 return android::hardware::PrintInstanceNameToString(
420 testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
421 });
422
423// Instantiate the test for each AIDL Weaver service.
424INSTANTIATE_TEST_SUITE_P(
425 PerAidlInstance, WeaverTest,
426 testing::Combine(testing::Values("aidl"),
427 testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor))),
428 [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
429 // This name_generator makes the instance name be included in the test case names, e.g.
430 // "PerAidlInstance/WeaverTest#GetConfig/0_android_hardware_weaver_IWeaver_default"
431 // instead of "PerAidlInstance/WeaverTest#GetConfig/0".
432 return android::PrintInstanceNameToString(
433 testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
434 });
ChengYou Ho10f8a482021-01-02 22:45:32 +0800435
436int main(int argc, char** argv) {
437 ::testing::InitGoogleTest(&argc, argv);
438 ABinderProcess_setThreadPoolMaxThreadCount(1);
439 ABinderProcess_startThreadPool();
440 return RUN_ALL_TESTS();
441}