blob: 047481e1231ddf78d88d423dceeb26cc2ddd0d5c [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
Eric Biggers961a1382023-07-18 02:34:00 +0000169 std::unique_ptr<WeaverAdapter> weaver_;
170 WeaverConfig config_;
Eric Biggersb59654f2023-07-18 02:33:59 +0000171};
172
173void WeaverTest::SetUp() {
174 std::string api, instance_name;
175 std::tie(api, instance_name) = GetParam();
176 if (api == "hidl") {
Eric Biggers961a1382023-07-18 02:34:00 +0000177 weaver_.reset(new WeaverHidlAdapter(instance_name));
Eric Biggersb59654f2023-07-18 02:33:59 +0000178 } else if (api == "aidl") {
Eric Biggers961a1382023-07-18 02:34:00 +0000179 weaver_.reset(new WeaverAidlAdapter(instance_name));
Eric Biggersb59654f2023-07-18 02:33:59 +0000180 } else {
181 FAIL() << "Bad test parameterization";
182 }
Eric Biggers961a1382023-07-18 02:34:00 +0000183 ASSERT_TRUE(weaver_->isReady());
184
185 auto ret = weaver_->getConfig(&config_);
186 ASSERT_TRUE(ret.isOk());
187 ASSERT_GT(config_.slots, 0);
188 GTEST_LOG_(INFO) << "WeaverConfig: slots=" << config_.slots << ", keySize=" << config_.keySize
189 << ", valueSize=" << config_.valueSize;
Eric Biggersb59654f2023-07-18 02:33:59 +0000190}
191
ChengYou Ho10f8a482021-01-02 22:45:32 +0800192/*
193 * Checks config values are suitably large
194 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000195TEST_P(WeaverTest, GetConfig) {
Eric Biggers961a1382023-07-18 02:34:00 +0000196 EXPECT_GE(config_.slots, 16u);
197 EXPECT_GE(config_.keySize, 16u);
198 EXPECT_GE(config_.valueSize, 16u);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800199}
200
201/*
202 * Gets the config twice and checks they are the same
203 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000204TEST_P(WeaverTest, GettingConfigMultipleTimesGivesSameResult) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800205 WeaverConfig config2;
206
Eric Biggers961a1382023-07-18 02:34:00 +0000207 auto ret = weaver_->getConfig(&config2);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800208 ASSERT_TRUE(ret.isOk());
209
Eric Biggers961a1382023-07-18 02:34:00 +0000210 EXPECT_EQ(config_, config2);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800211}
212
213/*
214 * Gets the number of slots from the config and writes a key and value to the last one
215 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000216TEST_P(WeaverTest, WriteToLastSlot) {
Eric Biggers961a1382023-07-18 02:34:00 +0000217 const uint32_t lastSlot = config_.slots - 1;
218 const auto writeRet = weaver_->write(lastSlot, KEY, VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800219 ASSERT_TRUE(writeRet.isOk());
220}
221
222/*
223 * Writes a key and value to a slot
224 * Reads the slot with the same key and receives the value that was previously written
225 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000226TEST_P(WeaverTest, WriteFollowedByReadGivesTheSameValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800227 constexpr uint32_t slotId = 0;
Eric Biggers961a1382023-07-18 02:34:00 +0000228 const auto ret = weaver_->write(slotId, KEY, VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800229 ASSERT_TRUE(ret.isOk());
230
231 WeaverReadResponse response;
Eric Biggers961a1382023-07-18 02:34:00 +0000232 const auto readRet = weaver_->read(slotId, KEY, &response);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800233 ASSERT_TRUE(readRet.isOk());
Eric Biggers961a1382023-07-18 02:34:00 +0000234 EXPECT_EQ(response.value, VALUE);
235 EXPECT_EQ(response.timeout, 0u);
236 EXPECT_EQ(response.status, WeaverReadStatus::OK);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800237}
238
239/*
240 * Writes a key and value to a slot
241 * Overwrites the slot with a new key and value
242 * Reads the slot with the new key and receives the new value
243 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000244TEST_P(WeaverTest, OverwritingSlotUpdatesTheValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800245 constexpr uint32_t slotId = 0;
Eric Biggers961a1382023-07-18 02:34:00 +0000246 const auto initialWriteRet = weaver_->write(slotId, WRONG_KEY, VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800247 ASSERT_TRUE(initialWriteRet.isOk());
248
Eric Biggers961a1382023-07-18 02:34:00 +0000249 const auto overwriteRet = weaver_->write(slotId, KEY, OTHER_VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800250 ASSERT_TRUE(overwriteRet.isOk());
251
252 WeaverReadResponse response;
Eric Biggers961a1382023-07-18 02:34:00 +0000253 const auto readRet = weaver_->read(slotId, KEY, &response);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800254 ASSERT_TRUE(readRet.isOk());
Eric Biggers961a1382023-07-18 02:34:00 +0000255 EXPECT_EQ(response.value, OTHER_VALUE);
256 EXPECT_EQ(response.timeout, 0u);
257 EXPECT_EQ(response.status, WeaverReadStatus::OK);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800258}
259
260/*
261 * Writes a key and value to a slot
262 * Reads the slot with a different key so does not receive the value
263 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000264TEST_P(WeaverTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800265 constexpr uint32_t slotId = 0;
Eric Biggers961a1382023-07-18 02:34:00 +0000266 const auto writeRet = weaver_->write(slotId, KEY, VALUE);
267 ASSERT_TRUE(writeRet.isOk());
ChengYou Ho10f8a482021-01-02 22:45:32 +0800268
269 WeaverReadResponse response;
Eric Biggers961a1382023-07-18 02:34:00 +0000270 const auto readRet = weaver_->read(slotId, WRONG_KEY, &response);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000271 ASSERT_TRUE(readRet.isOk());
Eric Biggers961a1382023-07-18 02:34:00 +0000272 EXPECT_TRUE(response.value.empty());
273 EXPECT_EQ(response.status, WeaverReadStatus::INCORRECT_KEY);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800274}
275
276/*
277 * Writing to an invalid slot fails
278 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000279TEST_P(WeaverTest, WritingToInvalidSlotFails) {
Eric Biggers961a1382023-07-18 02:34:00 +0000280 if (config_.slots == std::numeric_limits<uint32_t>::max()) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800281 // If there are no invalid slots then pass
282 return;
283 }
284
Eric Biggers961a1382023-07-18 02:34:00 +0000285 const auto writeRet = weaver_->write(config_.slots, KEY, VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800286 ASSERT_FALSE(writeRet.isOk());
287}
288
289/*
290 * Reading from an invalid slot fails rather than incorrect key
291 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000292TEST_P(WeaverTest, ReadingFromInvalidSlotFails) {
Eric Biggers961a1382023-07-18 02:34:00 +0000293 if (config_.slots == std::numeric_limits<uint32_t>::max()) {
ChengYou Ho10f8a482021-01-02 22:45:32 +0800294 // If there are no invalid slots then pass
295 return;
296 }
297
298 WeaverReadResponse response;
Eric Biggers961a1382023-07-18 02:34:00 +0000299 const auto readRet = weaver_->read(config_.slots, KEY, &response);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000300 ASSERT_TRUE(readRet.isOk());
Eric Biggers961a1382023-07-18 02:34:00 +0000301 EXPECT_TRUE(response.value.empty());
302 EXPECT_EQ(response.timeout, 0u);
303 EXPECT_EQ(response.status, WeaverReadStatus::FAILED);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800304}
305
306/*
307 * Writing a key that is too large fails
308 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000309TEST_P(WeaverTest, WriteWithTooLargeKeyFails) {
Eric Biggers961a1382023-07-18 02:34:00 +0000310 std::vector<uint8_t> bigKey(config_.keySize + 1);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800311
312 constexpr uint32_t slotId = 0;
Eric Biggers961a1382023-07-18 02:34:00 +0000313 const auto writeRet = weaver_->write(slotId, bigKey, VALUE);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800314 ASSERT_FALSE(writeRet.isOk());
315}
316
317/*
318 * Writing a value that is too large fails
319 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000320TEST_P(WeaverTest, WriteWithTooLargeValueFails) {
Eric Biggers961a1382023-07-18 02:34:00 +0000321 std::vector<uint8_t> bigValue(config_.valueSize + 1);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800322
323 constexpr uint32_t slotId = 0;
Eric Biggers961a1382023-07-18 02:34:00 +0000324 const auto writeRet = weaver_->write(slotId, KEY, bigValue);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800325 ASSERT_FALSE(writeRet.isOk());
326}
327
328/*
Eric Biggers961a1382023-07-18 02:34:00 +0000329 * Reading with a key that is too large fails
ChengYou Ho10f8a482021-01-02 22:45:32 +0800330 */
Eric Biggersb59654f2023-07-18 02:33:59 +0000331TEST_P(WeaverTest, ReadWithTooLargeKeyFails) {
Eric Biggers961a1382023-07-18 02:34:00 +0000332 std::vector<uint8_t> bigKey(config_.keySize + 1);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800333
334 constexpr uint32_t slotId = 0;
335 WeaverReadResponse response;
Eric Biggers961a1382023-07-18 02:34:00 +0000336 const auto readRet = weaver_->read(slotId, bigKey, &response);
ChengYou Ho20c47b42022-11-30 17:51:17 +0000337 ASSERT_TRUE(readRet.isOk());
Eric Biggers961a1382023-07-18 02:34:00 +0000338 EXPECT_TRUE(response.value.empty());
339 EXPECT_EQ(response.timeout, 0u);
340 EXPECT_EQ(response.status, WeaverReadStatus::FAILED);
ChengYou Ho10f8a482021-01-02 22:45:32 +0800341}
342
Eric Biggersb59654f2023-07-18 02:33:59 +0000343// Instantiate the test for each HIDL Weaver service.
ChengYou Ho10f8a482021-01-02 22:45:32 +0800344INSTANTIATE_TEST_SUITE_P(
Eric Biggersb59654f2023-07-18 02:33:59 +0000345 PerHidlInstance, WeaverTest,
346 testing::Combine(testing::Values("hidl"),
347 testing::ValuesIn(android::hardware::getAllHalInstanceNames(
348 HidlIWeaver::descriptor))),
349 [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
350 return android::hardware::PrintInstanceNameToString(
351 testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
352 });
353
354// Instantiate the test for each AIDL Weaver service.
355INSTANTIATE_TEST_SUITE_P(
356 PerAidlInstance, WeaverTest,
357 testing::Combine(testing::Values("aidl"),
358 testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor))),
359 [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
360 // This name_generator makes the instance name be included in the test case names, e.g.
361 // "PerAidlInstance/WeaverTest#GetConfig/0_android_hardware_weaver_IWeaver_default"
362 // instead of "PerAidlInstance/WeaverTest#GetConfig/0".
363 return android::PrintInstanceNameToString(
364 testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
365 });
ChengYou Ho10f8a482021-01-02 22:45:32 +0800366
367int main(int argc, char** argv) {
368 ::testing::InitGoogleTest(&argc, argv);
369 ABinderProcess_setThreadPoolMaxThreadCount(1);
370 ABinderProcess_startThreadPool();
371 return RUN_ALL_TESTS();
372}