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