1 /*
2 * Copyright (C) 2022 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 <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
18 #include <android/binder_ibinder.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <AidlHalPropValue.h>
23 #include <AidlVhalClient.h>
24 #include <VehicleHalTypes.h>
25 #include <VehicleUtils.h>
26
27 #include <atomic>
28 #include <condition_variable> // NOLINT
29 #include <mutex> // NOLINT
30 #include <thread> // NOLINT
31
32 namespace android {
33 namespace frameworks {
34 namespace automotive {
35 namespace vhal {
36 namespace aidl_test {
37
38 using ::android::hardware::automotive::vehicle::toInt;
39
40 using ::aidl::android::hardware::automotive::vehicle::BnVehicle;
41 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
42 using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
43 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
44 using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
45 using ::aidl::android::hardware::automotive::vehicle::IVehicle;
46 using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
47 using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResults;
48 using ::aidl::android::hardware::automotive::vehicle::PropIdAreaId;
49 using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
50 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
51 using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
52 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
53 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
54 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
55 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
56 using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResults;
57 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
58 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
59 using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
60 using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
61 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
62 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
63 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
64 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
65
66 using ::ndk::ScopedAStatus;
67 using ::ndk::SharedRefBase;
68 using ::testing::Gt;
69
70 class MockVhal final : public BnVehicle {
71 public:
72 using CallbackType = std::shared_ptr<IVehicleCallback>;
73
~MockVhal()74 ~MockVhal() {
75 std::unique_lock<std::mutex> lk(mLock);
76 mCv.wait_for(lk, std::chrono::milliseconds(1000), [this] { return mThreadCount == 0; });
77 }
78
getAllPropConfigs(VehiclePropConfigs * returnConfigs)79 ScopedAStatus getAllPropConfigs(VehiclePropConfigs* returnConfigs) override {
80 if (mStatus != StatusCode::OK) {
81 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
82 }
83
84 returnConfigs->payloads = mPropConfigs;
85 return ScopedAStatus::ok();
86 }
87
getValues(const CallbackType & callback,const GetValueRequests & requests)88 ScopedAStatus getValues(const CallbackType& callback,
89 const GetValueRequests& requests) override {
90 mGetValueRequests = requests.payloads;
91
92 if (mStatus != StatusCode::OK) {
93 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
94 }
95
96 if (mWaitTimeInMs == 0) {
97 callback->onGetValues(GetValueResults{.payloads = mGetValueResults});
98 } else {
99 mThreadCount++;
100 std::thread t([this, callback]() {
101 std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTimeInMs));
102 callback->onGetValues(GetValueResults{.payloads = mGetValueResults});
103 mThreadCount--;
104 mCv.notify_one();
105 });
106 // Detach the thread here so we do not have to maintain the thread object. mThreadCount
107 // and mCv make sure we wait for all threads to end before we exit.
108 t.detach();
109 }
110 return ScopedAStatus::ok();
111 }
112
setValues(const CallbackType & callback,const SetValueRequests & requests)113 ScopedAStatus setValues(const CallbackType& callback,
114 const SetValueRequests& requests) override {
115 mSetValueRequests = requests.payloads;
116
117 if (mStatus != StatusCode::OK) {
118 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
119 }
120
121 if (mWaitTimeInMs == 0) {
122 callback->onSetValues(SetValueResults{.payloads = mSetValueResults});
123 } else {
124 mThreadCount++;
125 std::thread t([this, callback]() {
126 std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTimeInMs));
127 callback->onSetValues(SetValueResults{.payloads = mSetValueResults});
128 mThreadCount--;
129 mCv.notify_one();
130 });
131 // Detach the thread here so we do not have to maintain the thread object. mThreadCount
132 // and mCv make sure we wait for all threads to end before we exit.
133 t.detach();
134 }
135 return ScopedAStatus::ok();
136 }
137
getPropConfigs(const std::vector<int32_t> & props,VehiclePropConfigs * returnConfigs)138 ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
139 VehiclePropConfigs* returnConfigs) override {
140 mGetPropConfigPropIds = props;
141 if (mStatus != StatusCode::OK) {
142 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
143 }
144
145 returnConfigs->payloads = mPropConfigs;
146 return ScopedAStatus::ok();
147 }
148
subscribe(const CallbackType & callback,const std::vector<SubscribeOptions> & options,int32_t maxSharedMemoryFileCount)149 ScopedAStatus subscribe(const CallbackType& callback,
150 const std::vector<SubscribeOptions>& options,
151 [[maybe_unused]] int32_t maxSharedMemoryFileCount) override {
152 mSubscriptionCallback = callback;
153 mSubscriptionOptions = options;
154
155 if (mStatus != StatusCode::OK) {
156 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
157 }
158 return ScopedAStatus::ok();
159 }
160
unsubscribe(const CallbackType & callback,const std::vector<int32_t> & propIds)161 ScopedAStatus unsubscribe([[maybe_unused]] const CallbackType& callback,
162 const std::vector<int32_t>& propIds) override {
163 mUnsubscribePropIds = propIds;
164
165 if (mStatus != StatusCode::OK) {
166 return ScopedAStatus::fromServiceSpecificError(toInt(mStatus));
167 }
168 return ScopedAStatus::ok();
169 }
170
returnSharedMemory(const CallbackType & callback,int64_t sharedMemoryId)171 ScopedAStatus returnSharedMemory([[maybe_unused]] const CallbackType& callback,
172 [[maybe_unused]] int64_t sharedMemoryId) override {
173 return ScopedAStatus::ok();
174 }
175
getSupportedValuesLists(const std::vector<PropIdAreaId> &,SupportedValuesListResults *)176 ScopedAStatus getSupportedValuesLists(const std::vector<PropIdAreaId>&,
177 SupportedValuesListResults*) {
178 return ScopedAStatus::ok();
179 }
180
getMinMaxSupportedValue(const std::vector<PropIdAreaId> &,MinMaxSupportedValueResults *)181 ScopedAStatus getMinMaxSupportedValue(const std::vector<PropIdAreaId>&,
182 MinMaxSupportedValueResults*) {
183 return ScopedAStatus::ok();
184 }
185
registerSupportedValueChangeCallback(const std::shared_ptr<IVehicleCallback> &,const std::vector<PropIdAreaId> &)186 ScopedAStatus registerSupportedValueChangeCallback(const std::shared_ptr<IVehicleCallback>&,
187 const std::vector<PropIdAreaId>&) {
188 return ScopedAStatus::ok();
189 }
190
unregisterSupportedValueChangeCallback(const std::shared_ptr<IVehicleCallback> &,const std::vector<PropIdAreaId> &)191 ScopedAStatus unregisterSupportedValueChangeCallback(const std::shared_ptr<IVehicleCallback>&,
192 const std::vector<PropIdAreaId>&) {
193 return ScopedAStatus::ok();
194 }
195
196 // Test Functions
197
setGetValueResults(std::vector<GetValueResult> results)198 void setGetValueResults(std::vector<GetValueResult> results) { mGetValueResults = results; }
199
getGetValueRequests()200 std::vector<GetValueRequest> getGetValueRequests() { return mGetValueRequests; }
201
setSetValueResults(std::vector<SetValueResult> results)202 void setSetValueResults(std::vector<SetValueResult> results) { mSetValueResults = results; }
203
getSetValueRequests()204 std::vector<SetValueRequest> getSetValueRequests() { return mSetValueRequests; }
205
setWaitTimeInMs(int64_t waitTimeInMs)206 void setWaitTimeInMs(int64_t waitTimeInMs) { mWaitTimeInMs = waitTimeInMs; }
207
setStatus(StatusCode status)208 void setStatus(StatusCode status) { mStatus = status; }
209
setPropConfigs(std::vector<VehiclePropConfig> configs)210 void setPropConfigs(std::vector<VehiclePropConfig> configs) { mPropConfigs = configs; }
211
getGetPropConfigPropIds()212 std::vector<int32_t> getGetPropConfigPropIds() { return mGetPropConfigPropIds; }
213
getSubscriptionOptions()214 std::vector<SubscribeOptions> getSubscriptionOptions() { return mSubscriptionOptions; }
215
triggerOnPropertyEvent(const std::vector<VehiclePropValue> & values)216 void triggerOnPropertyEvent(const std::vector<VehiclePropValue>& values) {
217 VehiclePropValues propValues = {
218 .payloads = values,
219 };
220 mSubscriptionCallback->onPropertyEvent(propValues, /*sharedMemoryCount=*/0);
221 }
222
triggerSetErrorEvent(const std::vector<VehiclePropError> & errors)223 void triggerSetErrorEvent(const std::vector<VehiclePropError>& errors) {
224 VehiclePropErrors propErrors = {
225 .payloads = errors,
226 };
227 mSubscriptionCallback->onPropertySetError(propErrors);
228 }
229
getUnsubscribedPropIds()230 std::vector<int32_t> getUnsubscribedPropIds() { return mUnsubscribePropIds; }
231
232 private:
233 std::mutex mLock;
234 std::vector<GetValueResult> mGetValueResults;
235 std::vector<GetValueRequest> mGetValueRequests;
236 std::vector<SetValueResult> mSetValueResults;
237 std::vector<SetValueRequest> mSetValueRequests;
238 std::vector<VehiclePropConfig> mPropConfigs;
239 std::vector<int32_t> mGetPropConfigPropIds;
240 int64_t mWaitTimeInMs = 0;
241 StatusCode mStatus = StatusCode::OK;
242 std::condition_variable mCv;
243 std::atomic<int> mThreadCount = 0;
244 CallbackType mSubscriptionCallback;
245 std::vector<SubscribeOptions> mSubscriptionOptions;
246 std::vector<int32_t> mUnsubscribePropIds;
247 };
248
249 class MockSubscriptionCallback : public ISubscriptionCallback {
250 public:
onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>> & values)251 void onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>>& values) override {
252 for (const auto& value : values) {
253 mEventPropIds.push_back(value->getPropId());
254 }
255 }
onPropertySetError(const std::vector<HalPropError> & errors)256 void onPropertySetError(const std::vector<HalPropError>& errors) override { mErrors = errors; }
257
getEventPropIds()258 std::vector<int32_t> getEventPropIds() { return mEventPropIds; }
259
getErrors()260 std::vector<HalPropError> getErrors() { return mErrors; }
261
262 private:
263 std::vector<int32_t> mEventPropIds;
264 std::vector<HalPropError> mErrors;
265 };
266
267 class AidlVhalClientTest : public ::testing::Test {
268 protected:
269 class TestLinkUnlinkImpl final : public AidlVhalClient::ILinkUnlinkToDeath {
270 public:
linkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)271 binder_status_t linkToDeath([[maybe_unused]] AIBinder* binder,
272 [[maybe_unused]] AIBinder_DeathRecipient* recipient,
273 void* cookie) override {
274 mCookie = cookie;
275 mDeathRecipient = recipient;
276 return STATUS_OK;
277 }
278
deleteDeathRecipient(AIBinder_DeathRecipient * recipient)279 void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) override {
280 if (mDeathRecipient == recipient) {
281 triggerBinderUnlinked();
282 }
283 }
284
setOnUnlinked(AIBinder_DeathRecipient * recipient,AIBinder_DeathRecipient_onBinderUnlinked onUnlinked)285 void setOnUnlinked([[maybe_unused]] AIBinder_DeathRecipient* recipient,
286 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) override {
287 mOnUnlinked = onUnlinked;
288 }
289
getCookie()290 void* getCookie() { return mCookie; }
291
triggerBinderUnlinked()292 void triggerBinderUnlinked() {
293 if (mDeathRecipient == nullptr) {
294 // Already unlinked, do nothing.
295 return;
296 }
297 (*mOnUnlinked)(mCookie);
298 mDeathRecipient = nullptr;
299 }
300
301 private:
302 void* mCookie;
303 AIBinder_DeathRecipient_onBinderUnlinked mOnUnlinked;
304 AIBinder_DeathRecipient* mDeathRecipient;
305 };
306
307 constexpr static int32_t TEST_PROP_ID = 1;
308 constexpr static int32_t TEST_AREA_ID = 2;
309 constexpr static int32_t TEST_PROP_ID_2 = 3;
310 constexpr static int32_t TEST_AREA_ID_2 = 4;
311 constexpr static VehiclePropertyAccess TEST_GLOBAL_ACCESS = VehiclePropertyAccess::READ_WRITE;
312 constexpr static VehiclePropertyAccess TEST_AREA_ACCESS = VehiclePropertyAccess::READ;
313 constexpr static int64_t TEST_TIMEOUT_IN_MS = 100;
314
SetUp()315 void SetUp() override {
316 mVhal = SharedRefBase::make<MockVhal>();
317 auto impl = std::make_unique<TestLinkUnlinkImpl>();
318 // We are sure impl would be alive when we use mLinkUnlinkImpl.
319 mLinkUnlinkImpl = impl.get();
320 mVhalClient = std::unique_ptr<AidlVhalClient>(
321 new AidlVhalClient(mVhal, TEST_TIMEOUT_IN_MS, std::move(impl)));
322 }
323
getClient()324 AidlVhalClient* getClient() { return mVhalClient.get(); }
325
resetClient()326 void resetClient() { mVhalClient.reset(); }
327
getVhal()328 MockVhal* getVhal() { return mVhal.get(); }
329
triggerBinderDied()330 void triggerBinderDied() {
331 AidlVhalClient::onBinderDied(mLinkUnlinkImpl->getCookie());
332 mLinkUnlinkImpl->triggerBinderUnlinked();
333 }
334
countOnBinderDiedCallbacks()335 size_t countOnBinderDiedCallbacks() { return mVhalClient->countOnBinderDiedCallbacks(); }
336
337 private:
338 std::shared_ptr<MockVhal> mVhal;
339 std::unique_ptr<AidlVhalClient> mVhalClient;
340 TestLinkUnlinkImpl* mLinkUnlinkImpl;
341 };
342
TEST_F(AidlVhalClientTest,testIsAidl)343 TEST_F(AidlVhalClientTest, testIsAidl) {
344 ASSERT_TRUE(getClient()->isAidlVhal());
345 }
346
TEST_F(AidlVhalClientTest,testGetValueNormal)347 TEST_F(AidlVhalClientTest, testGetValueNormal) {
348 VehiclePropValue testProp{
349 .prop = TEST_PROP_ID,
350 .areaId = TEST_AREA_ID,
351 };
352 getVhal()->setWaitTimeInMs(10);
353 getVhal()->setGetValueResults({
354 GetValueResult{
355 .requestId = 0,
356 .status = StatusCode::OK,
357 .prop =
358 VehiclePropValue{
359 .prop = TEST_PROP_ID,
360 .areaId = TEST_AREA_ID,
361 .value =
362 RawPropValues{
363 .int32Values = {1},
364 },
365 },
366 },
367 });
368
369 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
370 std::mutex lock;
371 std::condition_variable cv;
372 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
373 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
374 bool gotResult = false;
375 bool* gotResultPtr = &gotResult;
376
377 auto callback = std::make_shared<AidlVhalClient::GetValueCallbackFunc>(
378 [&lock, &cv, resultPtr,
379 gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
380 {
381 std::lock_guard<std::mutex> lockGuard(lock);
382 *resultPtr = std::move(r);
383 *gotResultPtr = true;
384 }
385 cv.notify_one();
386 });
387 getClient()->getValue(propValue, callback);
388
389 std::unique_lock<std::mutex> lk(lock);
390 cv.wait_for(lk, std::chrono::milliseconds(1000), [&gotResult] { return gotResult; });
391
392 ASSERT_TRUE(gotResult);
393 ASSERT_EQ(getVhal()->getGetValueRequests(),
394 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
395 ASSERT_TRUE(result.ok());
396 auto gotValue = std::move(result.value());
397 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
398 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
399 ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::AVAILABLE);
400 ASSERT_EQ(gotValue->getInt32Values(), std::vector<int32_t>({1}));
401 }
402
TEST_F(AidlVhalClientTest,testGetValueSync)403 TEST_F(AidlVhalClientTest, testGetValueSync) {
404 VehiclePropValue testProp{
405 .prop = TEST_PROP_ID,
406 .areaId = TEST_AREA_ID,
407 };
408 getVhal()->setWaitTimeInMs(10);
409 getVhal()->setGetValueResults({
410 GetValueResult{
411 .requestId = 0,
412 .status = StatusCode::OK,
413 .prop =
414 VehiclePropValue{
415 .prop = TEST_PROP_ID,
416 .areaId = TEST_AREA_ID,
417 .value =
418 RawPropValues{
419 .int32Values = {1},
420 },
421 },
422 },
423 });
424
425 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
426 VhalClientResult<std::unique_ptr<IHalPropValue>> result = getClient()->getValueSync(propValue);
427
428 ASSERT_EQ(getVhal()->getGetValueRequests(),
429 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
430 ASSERT_TRUE(result.ok());
431 auto gotValue = std::move(result.value());
432 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
433 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
434 ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::AVAILABLE);
435 ASSERT_EQ(gotValue->getInt32Values(), std::vector<int32_t>({1}));
436 }
437
TEST_F(AidlVhalClientTest,testGetValueUnavailableStatusSync)438 TEST_F(AidlVhalClientTest, testGetValueUnavailableStatusSync) {
439 VehiclePropValue testProp{
440 .prop = TEST_PROP_ID,
441 .areaId = TEST_AREA_ID,
442 };
443 getVhal()->setWaitTimeInMs(10);
444 getVhal()->setGetValueResults({
445 GetValueResult{
446 .requestId = 0,
447 .status = StatusCode::OK,
448 .prop =
449 VehiclePropValue{
450 .prop = TEST_PROP_ID,
451 .areaId = TEST_AREA_ID,
452 .status = VehiclePropertyStatus::UNAVAILABLE,
453 },
454 },
455 });
456
457 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
458 VhalClientResult<std::unique_ptr<IHalPropValue>> result = getClient()->getValueSync(propValue);
459
460 ASSERT_EQ(getVhal()->getGetValueRequests(),
461 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
462 ASSERT_TRUE(result.ok());
463 auto gotValue = std::move(result.value());
464 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
465 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
466 ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::UNAVAILABLE);
467 }
468
TEST_F(AidlVhalClientTest,testGetValueTimeout)469 TEST_F(AidlVhalClientTest, testGetValueTimeout) {
470 VehiclePropValue testProp{
471 .prop = TEST_PROP_ID,
472 .areaId = TEST_AREA_ID,
473 };
474 // The request will time-out before the response.
475 getVhal()->setWaitTimeInMs(200);
476 getVhal()->setGetValueResults({
477 GetValueResult{
478 .requestId = 0,
479 .status = StatusCode::OK,
480 .prop =
481 VehiclePropValue{
482 .prop = TEST_PROP_ID,
483 .areaId = TEST_AREA_ID,
484 .value =
485 RawPropValues{
486 .int32Values = {1},
487 },
488 },
489 },
490 });
491
492 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
493 std::mutex lock;
494 std::condition_variable cv;
495 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
496 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
497 bool gotResult = false;
498 bool* gotResultPtr = &gotResult;
499
500 auto callback = std::make_shared<AidlVhalClient::GetValueCallbackFunc>(
501 [&lock, &cv, resultPtr,
502 gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
503 {
504 std::lock_guard<std::mutex> lockGuard(lock);
505 *resultPtr = std::move(r);
506 *gotResultPtr = true;
507 }
508 cv.notify_one();
509 });
510 getClient()->getValue(propValue, callback);
511
512 std::unique_lock<std::mutex> lk(lock);
513 cv.wait_for(lk, std::chrono::milliseconds(1000), [&gotResult] { return gotResult; });
514
515 ASSERT_TRUE(gotResult);
516 ASSERT_EQ(getVhal()->getGetValueRequests(),
517 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
518 ASSERT_FALSE(result.ok());
519 ASSERT_EQ(result.error().code(), ErrorCode::TIMEOUT);
520 }
521
TEST_F(AidlVhalClientTest,testGetValueErrorStatus)522 TEST_F(AidlVhalClientTest, testGetValueErrorStatus) {
523 VehiclePropValue testProp{
524 .prop = TEST_PROP_ID,
525 .areaId = TEST_AREA_ID,
526 };
527 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
528
529 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
530 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
531 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
532
533 getClient()->getValue(propValue,
534 std::make_shared<AidlVhalClient::GetValueCallbackFunc>(
535 [resultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
536 *resultPtr = std::move(r);
537 }));
538
539 ASSERT_EQ(getVhal()->getGetValueRequests(),
540 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
541 ASSERT_FALSE(result.ok());
542 ASSERT_EQ(result.error().code(), ErrorCode::INTERNAL_ERROR_FROM_VHAL);
543 }
544
TEST_F(AidlVhalClientTest,testGetValueNonOkayResult)545 TEST_F(AidlVhalClientTest, testGetValueNonOkayResult) {
546 VehiclePropValue testProp{
547 .prop = TEST_PROP_ID,
548 .areaId = TEST_AREA_ID,
549 };
550 getVhal()->setGetValueResults({
551 GetValueResult{
552 .requestId = 0,
553 .status = StatusCode::INTERNAL_ERROR,
554 },
555 });
556
557 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
558 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
559 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
560
561 getClient()->getValue(propValue,
562 std::make_shared<AidlVhalClient::GetValueCallbackFunc>(
563 [resultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
564 *resultPtr = std::move(r);
565 }));
566
567 ASSERT_EQ(getVhal()->getGetValueRequests(),
568 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
569 ASSERT_FALSE(result.ok());
570 ASSERT_EQ(result.error().code(), ErrorCode::INTERNAL_ERROR_FROM_VHAL);
571 }
572
TEST_F(AidlVhalClientTest,testGetValueIgnoreInvalidRequestId)573 TEST_F(AidlVhalClientTest, testGetValueIgnoreInvalidRequestId) {
574 VehiclePropValue testProp{
575 .prop = TEST_PROP_ID,
576 .areaId = TEST_AREA_ID,
577 };
578 getVhal()->setGetValueResults({
579 GetValueResult{
580 .requestId = 0,
581 .status = StatusCode::OK,
582 .prop =
583 VehiclePropValue{
584 .prop = TEST_PROP_ID,
585 .areaId = TEST_AREA_ID,
586 .value =
587 RawPropValues{
588 .int32Values = {1},
589 },
590 },
591 },
592 // This result has invalid request ID and should be ignored.
593 GetValueResult{
594 .requestId = 1,
595 .status = StatusCode::INTERNAL_ERROR,
596 },
597 });
598
599 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
600 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
601 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
602
603 getClient()->getValue(propValue,
604 std::make_shared<AidlVhalClient::GetValueCallbackFunc>(
605 [resultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
606 *resultPtr = std::move(r);
607 }));
608
609 ASSERT_EQ(getVhal()->getGetValueRequests(),
610 std::vector<GetValueRequest>({GetValueRequest{.requestId = 0, .prop = testProp}}));
611 ASSERT_TRUE(result.ok());
612 auto gotValue = std::move(result.value());
613 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
614 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
615 ASSERT_EQ(gotValue->getInt32Values(), std::vector<int32_t>({1}));
616 }
617
TEST_F(AidlVhalClientTest,testSetValueNormal)618 TEST_F(AidlVhalClientTest, testSetValueNormal) {
619 VehiclePropValue testProp{
620 .prop = TEST_PROP_ID,
621 .areaId = TEST_AREA_ID,
622 };
623 getVhal()->setWaitTimeInMs(10);
624 getVhal()->setSetValueResults({
625 SetValueResult{
626 .requestId = 0,
627 .status = StatusCode::OK,
628 },
629 });
630
631 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
632 std::mutex lock;
633 std::condition_variable cv;
634 VhalClientResult<void> result;
635 VhalClientResult<void>* resultPtr = &result;
636 bool gotResult = false;
637 bool* gotResultPtr = &gotResult;
638
639 auto callback = std::make_shared<AidlVhalClient::SetValueCallbackFunc>(
640 [&lock, &cv, resultPtr, gotResultPtr](VhalClientResult<void> r) {
641 {
642 std::lock_guard<std::mutex> lockGuard(lock);
643 *resultPtr = std::move(r);
644 *gotResultPtr = true;
645 }
646 cv.notify_one();
647 });
648 getClient()->setValue(propValue, callback);
649
650 std::unique_lock<std::mutex> lk(lock);
651 cv.wait_for(lk, std::chrono::milliseconds(1000), [&gotResult] { return gotResult; });
652
653 ASSERT_TRUE(gotResult);
654 ASSERT_EQ(getVhal()->getSetValueRequests(),
655 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
656 ASSERT_TRUE(result.ok());
657 }
658
TEST_F(AidlVhalClientTest,testSetValueSync)659 TEST_F(AidlVhalClientTest, testSetValueSync) {
660 VehiclePropValue testProp{
661 .prop = TEST_PROP_ID,
662 .areaId = TEST_AREA_ID,
663 };
664 getVhal()->setWaitTimeInMs(10);
665 getVhal()->setSetValueResults({
666 SetValueResult{
667 .requestId = 0,
668 .status = StatusCode::OK,
669 },
670 });
671
672 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
673 VhalClientResult<void> result = getClient()->setValueSync(propValue);
674
675 ASSERT_EQ(getVhal()->getSetValueRequests(),
676 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
677 ASSERT_TRUE(result.ok());
678 }
679
TEST_F(AidlVhalClientTest,testSetValueTimeout)680 TEST_F(AidlVhalClientTest, testSetValueTimeout) {
681 VehiclePropValue testProp{
682 .prop = TEST_PROP_ID,
683 .areaId = TEST_AREA_ID,
684 };
685 // The request will time-out before the response.
686 getVhal()->setWaitTimeInMs(200);
687 getVhal()->setSetValueResults({
688 SetValueResult{
689 .requestId = 0,
690 .status = StatusCode::OK,
691 },
692 });
693
694 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
695 std::mutex lock;
696 std::condition_variable cv;
697 VhalClientResult<void> result;
698 VhalClientResult<void>* resultPtr = &result;
699 bool gotResult = false;
700 bool* gotResultPtr = &gotResult;
701
702 auto callback = std::make_shared<AidlVhalClient::SetValueCallbackFunc>(
703 [&lock, &cv, resultPtr, gotResultPtr](VhalClientResult<void> r) {
704 {
705 std::lock_guard<std::mutex> lockGuard(lock);
706 *resultPtr = std::move(r);
707 *gotResultPtr = true;
708 }
709 cv.notify_one();
710 });
711 getClient()->setValue(propValue, callback);
712
713 std::unique_lock<std::mutex> lk(lock);
714 cv.wait_for(lk, std::chrono::milliseconds(1000), [&gotResult] { return gotResult; });
715
716 ASSERT_TRUE(gotResult);
717 ASSERT_EQ(getVhal()->getSetValueRequests(),
718 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
719 ASSERT_FALSE(result.ok());
720 ASSERT_EQ(result.error().code(), ErrorCode::TIMEOUT);
721 }
722
TEST_F(AidlVhalClientTest,testSetValueErrorStatus)723 TEST_F(AidlVhalClientTest, testSetValueErrorStatus) {
724 VehiclePropValue testProp{
725 .prop = TEST_PROP_ID,
726 .areaId = TEST_AREA_ID,
727 };
728 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
729
730 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
731 VhalClientResult<void> result;
732 VhalClientResult<void>* resultPtr = &result;
733
734 getClient()->setValue(propValue,
735 std::make_shared<AidlVhalClient::SetValueCallbackFunc>(
736 [resultPtr](VhalClientResult<void> r) {
737 *resultPtr = std::move(r);
738 }));
739
740 ASSERT_EQ(getVhal()->getSetValueRequests(),
741 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
742 ASSERT_FALSE(result.ok());
743 ASSERT_EQ(result.error().code(), ErrorCode::INTERNAL_ERROR_FROM_VHAL);
744 }
745
TEST_F(AidlVhalClientTest,testSetValueNonOkayResult)746 TEST_F(AidlVhalClientTest, testSetValueNonOkayResult) {
747 VehiclePropValue testProp{
748 .prop = TEST_PROP_ID,
749 .areaId = TEST_AREA_ID,
750 };
751 getVhal()->setSetValueResults({
752 SetValueResult{
753 .requestId = 0,
754 .status = StatusCode::INTERNAL_ERROR,
755 },
756 });
757
758 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
759 VhalClientResult<void> result;
760 VhalClientResult<void>* resultPtr = &result;
761
762 getClient()->setValue(propValue,
763 std::make_shared<AidlVhalClient::SetValueCallbackFunc>(
764 [resultPtr](VhalClientResult<void> r) {
765 *resultPtr = std::move(r);
766 }));
767
768 ASSERT_EQ(getVhal()->getSetValueRequests(),
769 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
770 ASSERT_FALSE(result.ok());
771 ASSERT_EQ(result.error().code(), ErrorCode::INTERNAL_ERROR_FROM_VHAL);
772 }
773
TEST_F(AidlVhalClientTest,testSetValueIgnoreInvalidRequestId)774 TEST_F(AidlVhalClientTest, testSetValueIgnoreInvalidRequestId) {
775 VehiclePropValue testProp{
776 .prop = TEST_PROP_ID,
777 .areaId = TEST_AREA_ID,
778 };
779 getVhal()->setSetValueResults({
780 SetValueResult{
781 .requestId = 0,
782 .status = StatusCode::OK,
783 },
784 // This result has invalid request ID and should be ignored.
785 SetValueResult{
786 .requestId = 1,
787 .status = StatusCode::INTERNAL_ERROR,
788 },
789 });
790
791 AidlHalPropValue propValue(TEST_PROP_ID, TEST_AREA_ID);
792 VhalClientResult<void> result;
793 VhalClientResult<void>* resultPtr = &result;
794
795 getClient()->setValue(propValue,
796 std::make_shared<AidlVhalClient::SetValueCallbackFunc>(
797 [resultPtr](VhalClientResult<void> r) {
798 *resultPtr = std::move(r);
799 }));
800
801 ASSERT_EQ(getVhal()->getSetValueRequests(),
802 std::vector<SetValueRequest>({SetValueRequest{.requestId = 0, .value = testProp}}));
803 ASSERT_TRUE(result.ok());
804 }
805
TEST_F(AidlVhalClientTest,testAddOnBinderDiedCallback)806 TEST_F(AidlVhalClientTest, testAddOnBinderDiedCallback) {
807 struct Result {
808 bool callbackOneCalled = false;
809 bool callbackTwoCalled = false;
810 } result;
811
812 getClient()->addOnBinderDiedCallback(std::make_shared<AidlVhalClient::OnBinderDiedCallbackFunc>(
813 [&result] { result.callbackOneCalled = true; }));
814 getClient()->addOnBinderDiedCallback(std::make_shared<AidlVhalClient::OnBinderDiedCallbackFunc>(
815 [&result] { result.callbackTwoCalled = true; }));
816 triggerBinderDied();
817
818 ASSERT_TRUE(result.callbackOneCalled);
819 ASSERT_TRUE(result.callbackTwoCalled);
820
821 ASSERT_EQ(countOnBinderDiedCallbacks(), static_cast<size_t>(0));
822 }
823
TEST_F(AidlVhalClientTest,testOnBinderDied_noDeadLock)824 TEST_F(AidlVhalClientTest, testOnBinderDied_noDeadLock) {
825 getClient()->addOnBinderDiedCallback(
826 std::make_shared<AidlVhalClient::OnBinderDiedCallbackFunc>([this] {
827 // This will trigger the destructor for AidlVhalClient. This must not cause dead
828 // lock.
829 resetClient();
830 }));
831
832 triggerBinderDied();
833 }
834
TEST_F(AidlVhalClientTest,testRemoveOnBinderDiedCallback)835 TEST_F(AidlVhalClientTest, testRemoveOnBinderDiedCallback) {
836 struct Result {
837 bool callbackOneCalled = false;
838 bool callbackTwoCalled = false;
839 } result;
840
841 auto callbackOne = std::make_shared<AidlVhalClient::OnBinderDiedCallbackFunc>(
842 [&result] { result.callbackOneCalled = true; });
843 auto callbackTwo = std::make_shared<AidlVhalClient::OnBinderDiedCallbackFunc>(
844 [&result] { result.callbackTwoCalled = true; });
845 getClient()->addOnBinderDiedCallback(callbackOne);
846 getClient()->addOnBinderDiedCallback(callbackTwo);
847 getClient()->removeOnBinderDiedCallback(callbackOne);
848 triggerBinderDied();
849
850 ASSERT_FALSE(result.callbackOneCalled);
851 ASSERT_TRUE(result.callbackTwoCalled);
852 ASSERT_EQ(countOnBinderDiedCallbacks(), static_cast<size_t>(0));
853 }
854
TEST_F(AidlVhalClientTest,testGetAllPropConfigs)855 TEST_F(AidlVhalClientTest, testGetAllPropConfigs) {
856 getVhal()->setPropConfigs({
857 VehiclePropConfig{
858 .prop = TEST_PROP_ID,
859 .access = TEST_GLOBAL_ACCESS,
860 .areaConfigs = {{
861 .areaId = TEST_AREA_ID,
862 .minInt32Value = 0,
863 .maxInt32Value = 1,
864 .supportVariableUpdateRate = true,
865 },
866 {
867 .areaId = TEST_AREA_ID_2,
868 .access = TEST_AREA_ACCESS,
869 .minInt32Value = 2,
870 .maxInt32Value = 3,
871 }},
872 },
873 VehiclePropConfig{
874 .prop = TEST_PROP_ID_2,
875 },
876 });
877
878 auto result = getClient()->getAllPropConfigs();
879
880 ASSERT_TRUE(result.ok());
881 std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
882
883 ASSERT_EQ(configs.size(), static_cast<size_t>(2));
884 ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
885 ASSERT_EQ(configs[0]->getAccess(), toInt(TEST_GLOBAL_ACCESS));
886 ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
887
888 const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
889 ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
890 ASSERT_EQ(areaConfig0->getAccess(), toInt(TEST_GLOBAL_ACCESS));
891 ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
892 ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
893 ASSERT_TRUE(areaConfig0->isVariableUpdateRateSupported());
894
895 const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
896 ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
897 ASSERT_EQ(areaConfig1->getAccess(), toInt(TEST_AREA_ACCESS));
898 ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
899 ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
900 ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
901
902 ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
903 ASSERT_EQ(configs[1]->getAccess(), 0);
904 ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
905
906 const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
907 ASSERT_EQ(areaConfig2->getAreaId(), 0);
908 ASSERT_EQ(areaConfig2->getAccess(), 0);
909 ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
910 }
911
TEST_F(AidlVhalClientTest,testGetAllPropConfigsError)912 TEST_F(AidlVhalClientTest, testGetAllPropConfigsError) {
913 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
914
915 auto result = getClient()->getAllPropConfigs();
916
917 ASSERT_FALSE(result.ok());
918 ASSERT_EQ(result.error().code(), ErrorCode::INTERNAL_ERROR_FROM_VHAL);
919 }
920
TEST_F(AidlVhalClientTest,testGetPropConfigs)921 TEST_F(AidlVhalClientTest, testGetPropConfigs) {
922 getVhal()->setPropConfigs({
923 VehiclePropConfig{
924 .prop = TEST_PROP_ID,
925 .access = TEST_GLOBAL_ACCESS,
926 .areaConfigs = {{
927 .areaId = TEST_AREA_ID,
928 .minInt32Value = 0,
929 .maxInt32Value = 1,
930 .supportVariableUpdateRate = true,
931 },
932 {
933 .areaId = TEST_AREA_ID_2,
934 .access = TEST_AREA_ACCESS,
935 .minInt32Value = 2,
936 .maxInt32Value = 3,
937 }},
938 },
939 VehiclePropConfig{
940 .prop = TEST_PROP_ID_2,
941 },
942 });
943
944 std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
945 auto result = getClient()->getPropConfigs(propIds);
946
947 ASSERT_EQ(getVhal()->getGetPropConfigPropIds(), propIds);
948 ASSERT_TRUE(result.ok());
949 std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
950
951 ASSERT_EQ(configs.size(), static_cast<size_t>(2));
952 ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
953 ASSERT_EQ(configs[0]->getAccess(), toInt(TEST_GLOBAL_ACCESS));
954 ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
955
956 const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
957 ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
958 ASSERT_EQ(areaConfig0->getAccess(), toInt(TEST_GLOBAL_ACCESS));
959 ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
960 ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
961 ASSERT_TRUE(areaConfig0->isVariableUpdateRateSupported());
962
963 const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
964 ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
965 ASSERT_EQ(areaConfig1->getAccess(), toInt(TEST_AREA_ACCESS));
966 ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
967 ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
968 ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
969
970 ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
971 ASSERT_EQ(configs[1]->getAccess(), 0);
972 ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
973
974 const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
975 ASSERT_EQ(areaConfig2->getAreaId(), 0);
976 ASSERT_EQ(areaConfig2->getAccess(), 0);
977 ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
978 }
979
TEST_F(AidlVhalClientTest,testGetPropConfigsError)980 TEST_F(AidlVhalClientTest, testGetPropConfigsError) {
981 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
982
983 std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
984 auto result = getClient()->getPropConfigs(propIds);
985
986 ASSERT_FALSE(result.ok());
987 }
988
TEST_F(AidlVhalClientTest,testSubscribe)989 TEST_F(AidlVhalClientTest, testSubscribe) {
990 std::vector<SubscribeOptions> options = {
991 {
992 .propId = TEST_PROP_ID,
993 .areaIds = {TEST_AREA_ID},
994 .sampleRate = 1.0,
995 },
996 {
997 .propId = TEST_PROP_ID_2,
998 .sampleRate = 2.0,
999 },
1000 };
1001
1002 auto callback = std::make_shared<MockSubscriptionCallback>();
1003 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
1004 auto result = subscriptionClient->subscribe(options);
1005
1006 ASSERT_TRUE(result.ok());
1007 ASSERT_EQ(getVhal()->getSubscriptionOptions(), options);
1008
1009 getVhal()->triggerOnPropertyEvent(std::vector<VehiclePropValue>{
1010 {
1011 .prop = TEST_PROP_ID,
1012 .areaId = TEST_AREA_ID,
1013 .value.int32Values = {1},
1014 },
1015 });
1016
1017 ASSERT_EQ(callback->getEventPropIds(), std::vector<int32_t>({TEST_PROP_ID}));
1018
1019 getVhal()->triggerSetErrorEvent(std::vector<VehiclePropError>({
1020 {
1021 .propId = TEST_PROP_ID,
1022 .areaId = TEST_AREA_ID,
1023 .errorCode = StatusCode::INTERNAL_ERROR,
1024 },
1025 }));
1026
1027 auto errors = callback->getErrors();
1028 ASSERT_EQ(errors.size(), static_cast<size_t>(1));
1029 ASSERT_EQ(errors[0].propId, TEST_PROP_ID);
1030 ASSERT_EQ(errors[0].areaId, TEST_AREA_ID);
1031 ASSERT_EQ(errors[0].status, StatusCode::INTERNAL_ERROR);
1032 }
1033
TEST_F(AidlVhalClientTest,testSubscribeError)1034 TEST_F(AidlVhalClientTest, testSubscribeError) {
1035 std::vector<SubscribeOptions> options = {
1036 {
1037 .propId = TEST_PROP_ID,
1038 .areaIds = {TEST_AREA_ID},
1039 .sampleRate = 1.0,
1040 },
1041 {
1042 .propId = TEST_PROP_ID_2,
1043 .sampleRate = 2.0,
1044 },
1045 };
1046
1047 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
1048 auto callback = std::make_shared<MockSubscriptionCallback>();
1049 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
1050 auto result = subscriptionClient->subscribe(options);
1051
1052 ASSERT_FALSE(result.ok());
1053 }
1054
TEST_F(AidlVhalClientTest,testUnubscribe)1055 TEST_F(AidlVhalClientTest, testUnubscribe) {
1056 auto callback = std::make_shared<MockSubscriptionCallback>();
1057 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
1058 auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
1059
1060 ASSERT_TRUE(result.ok());
1061 ASSERT_EQ(getVhal()->getUnsubscribedPropIds(), std::vector<int32_t>({TEST_PROP_ID}));
1062 }
1063
TEST_F(AidlVhalClientTest,testUnubscribeError)1064 TEST_F(AidlVhalClientTest, testUnubscribeError) {
1065 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
1066 auto callback = std::make_shared<MockSubscriptionCallback>();
1067 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
1068 auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
1069
1070 ASSERT_FALSE(result.ok());
1071 }
1072
TEST_F(AidlVhalClientTest,testGetRemoteInterfaceVersion)1073 TEST_F(AidlVhalClientTest, testGetRemoteInterfaceVersion) {
1074 // The AIDL VHAL should be v2 or higher.
1075 ASSERT_THAT(getClient()->getRemoteInterfaceVersion(), Gt(1));
1076 }
1077
TEST_F(AidlVhalClientTest,testSubscribeOptionsBuilder)1078 TEST_F(AidlVhalClientTest, testSubscribeOptionsBuilder) {
1079 auto optionsBuilder = SubscribeOptionsBuilder(TEST_PROP_ID);
1080 optionsBuilder.setSampleRate(1.23f);
1081 optionsBuilder.addAreaId(1);
1082 optionsBuilder.addAreaId(2);
1083 optionsBuilder.setResolution(2.34f);
1084
1085 auto options = optionsBuilder.build();
1086
1087 ASSERT_EQ(options,
1088 (SubscribeOptions{
1089 .propId = TEST_PROP_ID,
1090 .areaIds = {1, 2},
1091 .sampleRate = 1.23f,
1092 .resolution = 2.34f,
1093 // VUR is true by default
1094 .enableVariableUpdateRate = true,
1095 }));
1096 }
1097
TEST_F(AidlVhalClientTest,testSubscribeOptionsBuilder_disableVur)1098 TEST_F(AidlVhalClientTest, testSubscribeOptionsBuilder_disableVur) {
1099 auto optionsBuilder = SubscribeOptionsBuilder(TEST_PROP_ID);
1100 optionsBuilder.setSampleRate(1.23f);
1101 optionsBuilder.addAreaId(1);
1102 optionsBuilder.addAreaId(2);
1103 optionsBuilder.setResolution(2.34f);
1104 optionsBuilder.setEnableVariableUpdateRate(false);
1105
1106 auto options = optionsBuilder.build();
1107
1108 ASSERT_EQ(options,
1109 (SubscribeOptions{
1110 .propId = TEST_PROP_ID,
1111 .areaIds = {1, 2},
1112 .sampleRate = 1.23f,
1113 .resolution = 2.34f,
1114 .enableVariableUpdateRate = false,
1115 }));
1116 }
1117
TEST_F(AidlVhalClientTest,testAidlHalPropValueClone_valueIsTheSame)1118 TEST_F(AidlVhalClientTest, testAidlHalPropValueClone_valueIsTheSame) {
1119 VehiclePropValue testProp{.prop = TEST_PROP_ID,
1120 .areaId = TEST_AREA_ID,
1121 .value = {
1122 .int32Values = {1, 2},
1123 .floatValues = {1.1, 2.2},
1124 }};
1125 auto testPropCopy = testProp;
1126 std::unique_ptr<IHalPropValue> halPropValue =
1127 std::make_unique<AidlHalPropValue>(std::move(testPropCopy));
1128 auto halPropValueClone = halPropValue->clone();
1129
1130 EXPECT_EQ(halPropValueClone->getPropId(), TEST_PROP_ID);
1131 EXPECT_EQ(halPropValueClone->getAreaId(), TEST_AREA_ID);
1132 EXPECT_EQ(halPropValueClone->getInt32Values(), std::vector<int32_t>({1, 2}));
1133 EXPECT_EQ(halPropValueClone->getFloatValues(), std::vector<float>({1.1, 2.2}));
1134 }
1135
TEST_F(AidlVhalClientTest,testAidlHalPropValueClone_modifyCloneDoesNotAffectOrig)1136 TEST_F(AidlVhalClientTest, testAidlHalPropValueClone_modifyCloneDoesNotAffectOrig) {
1137 std::vector<int32_t> int32Values1 = {1, 2};
1138 std::vector<float> floatValues1 = {1.1, 2.2};
1139 std::vector<int32_t> int32Values2 = {5, 4, 3, 2, 1};
1140 std::vector<float> floatValues2 = {3.3, 2.2, 1.1};
1141
1142 VehiclePropValue testProp{.prop = TEST_PROP_ID,
1143 .areaId = TEST_AREA_ID,
1144 .value = {
1145 .int32Values = int32Values1,
1146 .floatValues = floatValues1,
1147 }};
1148 auto testPropCopy = testProp;
1149 std::unique_ptr<IHalPropValue> halPropValue =
1150 std::make_unique<AidlHalPropValue>(std::move(testPropCopy));
1151 auto halPropValueClone = halPropValue->clone();
1152
1153 halPropValueClone->setInt32Values(int32Values2);
1154 halPropValueClone->setFloatValues(floatValues2);
1155
1156 EXPECT_EQ(halPropValue->getInt32Values(), int32Values1);
1157 EXPECT_EQ(halPropValue->getFloatValues(), floatValues1);
1158 EXPECT_EQ(halPropValueClone->getInt32Values(), int32Values2);
1159 EXPECT_EQ(halPropValueClone->getFloatValues(), floatValues2);
1160 }
1161
1162 } // namespace aidl_test
1163 } // namespace vhal
1164 } // namespace automotive
1165 } // namespace frameworks
1166 } // namespace android
1167