• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "ConnectedClient.h"
18 #include "DefaultVehicleHal.h"
19 #include "MockVehicleCallback.h"
20 #include "MockVehicleHardware.h"
21 
22 #include <IVehicleHardware.h>
23 #include <LargeParcelableBase.h>
24 #include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
25 #include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
26 
27 #include <android-base/thread_annotations.h>
28 #include <gmock/gmock.h>
29 #include <gtest/gtest.h>
30 #include <sys/mman.h>
31 #include <utils/Log.h>
32 #include <utils/SystemClock.h>
33 
34 #include <chrono>
35 #include <list>
36 #include <memory>
37 #include <mutex>
38 #include <optional>
39 #include <thread>
40 #include <unordered_map>
41 #include <vector>
42 
43 namespace android {
44 namespace hardware {
45 namespace automotive {
46 namespace vehicle {
47 
48 namespace {
49 
50 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
51 using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
52 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
53 using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
54 using ::aidl::android::hardware::automotive::vehicle::IVehicle;
55 using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
56 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
57 using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
58 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
59 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
60 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
61 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
62 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
63 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
64 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
65 using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
66 using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
67 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
68 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
69 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
70 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
71 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
72 
73 using ::android::automotive::car_binder_lib::LargeParcelableBase;
74 using ::android::base::Result;
75 
76 using ::ndk::ScopedAStatus;
77 using ::ndk::ScopedFileDescriptor;
78 using ::ndk::SpAIBinder;
79 
80 using ::testing::ContainsRegex;
81 using ::testing::Eq;
82 using ::testing::UnorderedElementsAre;
83 using ::testing::UnorderedElementsAreArray;
84 using ::testing::WhenSortedBy;
85 
86 constexpr int32_t INVALID_PROP_ID = 0;
87 // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
88 constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;
89 // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
90 constexpr int32_t GLOBAL_ON_CHANGE_PROP = 10002 + 0x10000000 + 0x01000000 + 0x00400000;
91 // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
92 constexpr int32_t GLOBAL_CONTINUOUS_PROP = 10003 + 0x10000000 + 0x01000000 + 0x00400000;
93 // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
94 constexpr int32_t AREA_ON_CHANGE_PROP = 10004 + 0x10000000 + 0x03000000 + 0x00400000;
95 // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
96 constexpr int32_t AREA_CONTINUOUS_PROP = 10005 + 0x10000000 + 0x03000000 + 0x00400000;
97 // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
98 constexpr int32_t READ_ONLY_PROP = 10006 + 0x10000000 + 0x01000000 + 0x00400000;
99 // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
100 constexpr int32_t WRITE_ONLY_PROP = 10007 + 0x10000000 + 0x01000000 + 0x00400000;
101 
testInt32VecProp(size_t i)102 int32_t testInt32VecProp(size_t i) {
103     // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
104     return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
105 }
106 
107 struct PropConfigCmp {
operator ()android::hardware::automotive::vehicle::__anon060c6f7d0111::PropConfigCmp108     bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
109         return (a.prop < b.prop);
110     }
111 } propConfigCmp;
112 
113 struct SetValuesInvalidRequestTestCase {
114     std::string name;
115     VehiclePropValue request;
116     StatusCode expectedStatus;
117 };
118 
getSetValuesInvalidRequestTestCases()119 std::vector<SetValuesInvalidRequestTestCase> getSetValuesInvalidRequestTestCases() {
120     return {{
121                     .name = "config_not_found",
122                     .request =
123                             {
124                                     // No config for INVALID_PROP_ID.
125                                     .prop = INVALID_PROP_ID,
126                             },
127                     .expectedStatus = StatusCode::INVALID_ARG,
128             },
129             {
130                     .name = "invalid_prop_value",
131                     .request =
132                             {
133                                     .prop = testInt32VecProp(0),
134                                     // No int32Values for INT32_VEC property.
135                                     .value.int32Values = {},
136                             },
137                     .expectedStatus = StatusCode::INVALID_ARG,
138             },
139             {
140                     .name = "value_out_of_range",
141                     .request =
142                             {
143                                     .prop = testInt32VecProp(0),
144                                     // We configured the range to be 0-100.
145                                     .value.int32Values = {0, -1},
146                             },
147                     .expectedStatus = StatusCode::INVALID_ARG,
148             },
149             {
150                     .name = "invalid_area",
151                     .request =
152                             {
153                                     .prop = INT32_WINDOW_PROP,
154                                     .value.int32Values = {0},
155                                     // Only ROW_1_LEFT is allowed.
156                                     .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
157                             },
158                     .expectedStatus = StatusCode::INVALID_ARG,
159             },
160             {
161                     .name = "no_write_permission",
162                     .request =
163                             {
164                                     .prop = READ_ONLY_PROP,
165                                     .value.int32Values = {0},
166                             },
167                     .expectedStatus = StatusCode::ACCESS_DENIED,
168             }};
169 }
170 
171 struct SubscribeInvalidOptionsTestCase {
172     std::string name;
173     SubscribeOptions option;
174 };
175 
getSubscribeInvalidOptionsTestCases()176 std::vector<SubscribeInvalidOptionsTestCase> getSubscribeInvalidOptionsTestCases() {
177     return {{
178                     .name = "invalid_prop",
179                     .option =
180                             {
181                                     .propId = INVALID_PROP_ID,
182                             },
183             },
184             {
185                     .name = "invalid_area_ID",
186                     .option =
187                             {
188                                     .propId = AREA_ON_CHANGE_PROP,
189                                     .areaIds = {0},
190                             },
191             },
192             {
193                     .name = "invalid_sample_rate",
194                     .option =
195                             {
196                                     .propId = GLOBAL_CONTINUOUS_PROP,
197                                     .sampleRate = 0.0,
198                             },
199             },
200             {
201                     .name = "static_property",
202                     .option =
203                             {
204                                     // Default change mode is static.
205                                     .propId = testInt32VecProp(0),
206                             },
207             }};
208 }
209 
210 }  // namespace
211 
212 class DefaultVehicleHalTest : public testing::Test {
213   public:
SetUp()214     void SetUp() override {
215         auto hardware = std::make_unique<MockVehicleHardware>();
216         std::vector<VehiclePropConfig> testConfigs;
217         for (size_t i = 0; i < 10000; i++) {
218             testConfigs.push_back(VehiclePropConfig{
219                     .prop = testInt32VecProp(i),
220                     .access = VehiclePropertyAccess::READ_WRITE,
221                     .areaConfigs =
222                             {
223                                     {
224                                             .areaId = 0,
225                                             .minInt32Value = 0,
226                                             .maxInt32Value = 100,
227                                     },
228                             },
229             });
230         }
231         // A property with area config.
232         testConfigs.push_back(
233                 VehiclePropConfig{.prop = INT32_WINDOW_PROP,
234                                   .access = VehiclePropertyAccess::READ_WRITE,
235                                   .areaConfigs = {{
236                                           .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
237                                           .minInt32Value = 0,
238                                           .maxInt32Value = 100,
239                                   }}});
240         // A global on-change property.
241         testConfigs.push_back(VehiclePropConfig{
242                 .prop = GLOBAL_ON_CHANGE_PROP,
243                 .access = VehiclePropertyAccess::READ_WRITE,
244                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
245         });
246         // A global continuous property.
247         testConfigs.push_back(VehiclePropConfig{
248                 .prop = GLOBAL_CONTINUOUS_PROP,
249                 .access = VehiclePropertyAccess::READ_WRITE,
250                 .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
251                 .minSampleRate = 0.0,
252                 .maxSampleRate = 100.0,
253         });
254         // A per-area on-change property.
255         testConfigs.push_back(VehiclePropConfig{
256                 .prop = AREA_ON_CHANGE_PROP,
257                 .access = VehiclePropertyAccess::READ_WRITE,
258                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
259                 .areaConfigs =
260                         {
261                                 {
262 
263                                         .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
264                                         .minInt32Value = 0,
265                                         .maxInt32Value = 100,
266                                 },
267                                 {
268                                         .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
269                                         .minInt32Value = 0,
270                                         .maxInt32Value = 100,
271                                 },
272                         },
273         });
274         // A per-area continuous property.
275         testConfigs.push_back(VehiclePropConfig{
276                 .prop = AREA_CONTINUOUS_PROP,
277                 .access = VehiclePropertyAccess::READ_WRITE,
278                 .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
279                 .minSampleRate = 0.0,
280                 .maxSampleRate = 1000.0,
281                 .areaConfigs =
282                         {
283                                 {
284 
285                                         .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
286                                         .minInt32Value = 0,
287                                         .maxInt32Value = 100,
288                                 },
289                                 {
290                                         .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
291                                         .minInt32Value = 0,
292                                         .maxInt32Value = 100,
293                                 },
294                         },
295         });
296         // A read-only property.
297         testConfigs.push_back(VehiclePropConfig{
298                 .prop = READ_ONLY_PROP,
299                 .access = VehiclePropertyAccess::READ,
300                 .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
301                 .minSampleRate = 0.0,
302                 .maxSampleRate = 1000.0,
303         });
304         // A write-only property.
305         testConfigs.push_back(VehiclePropConfig{
306                 .prop = WRITE_ONLY_PROP,
307                 .access = VehiclePropertyAccess::WRITE,
308                 .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
309                 .minSampleRate = 0.0,
310                 .maxSampleRate = 1000.0,
311         });
312         // Register the heartbeat event property.
313         testConfigs.push_back(VehiclePropConfig{
314                 .prop = toInt(VehicleProperty::VHAL_HEARTBEAT),
315                 .access = VehiclePropertyAccess::READ,
316                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
317         });
318         hardware->setPropertyConfigs(testConfigs);
319         mHardwarePtr = hardware.get();
320         mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
321         mVhalClient = IVehicle::fromBinder(mVhal->asBinder());
322         mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
323         // Keep the local binder alive.
324         mBinder = mCallback->asBinder();
325         mCallbackClient = IVehicleCallback::fromBinder(mBinder);
326 
327         // Set the linkToDeath to a fake implementation that always returns OK.
328         auto handler = std::make_unique<TestBinderLifecycleHandler>();
329         mBinderLifecycleHandler = handler.get();
330         mVhal->setBinderLifecycleHandler(std::move(handler));
331     }
332 
TearDown()333     void TearDown() override {
334         ASSERT_EQ(countPendingRequests(), static_cast<size_t>(0))
335                 << "must have no pending requests when test finishes";
336     }
337 
getHardware()338     MockVehicleHardware* getHardware() { return mHardwarePtr; }
339 
getClient()340     std::shared_ptr<IVehicle> getClient() { return mVhal; }
341 
getCallbackClient()342     std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
343 
getCallback()344     MockVehicleCallback* getCallback() { return mCallback.get(); }
345 
setTimeout(int64_t timeoutInNano)346     void setTimeout(int64_t timeoutInNano) { mVhal->setTimeout(timeoutInNano); }
347 
countPendingRequests()348     size_t countPendingRequests() { return mVhal->mPendingRequestPool->countPendingRequests(); }
349 
countClients()350     size_t countClients() {
351         std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
352         return mVhal->mGetValuesClients.size() + mVhal->mSetValuesClients.size() +
353                mVhal->mSubscriptionClients->countClients();
354     }
355 
getPool()356     std::shared_ptr<PendingRequestPool> getPool() { return mVhal->mPendingRequestPool; }
357 
onBinderDied(void * cookie)358     void onBinderDied(void* cookie) { return mVhal->onBinderDied(cookie); }
359 
onBinderUnlinked(void * cookie)360     void onBinderUnlinked(void* cookie) { return mVhal->onBinderUnlinked(cookie); }
361 
getOnBinderDiedContexts(AIBinder * clientId)362     void* getOnBinderDiedContexts(AIBinder* clientId) {
363         std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
364         return mVhal->mOnBinderDiedContexts[clientId].get();
365     }
366 
countOnBinderDiedContexts()367     size_t countOnBinderDiedContexts() {
368         std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
369         return mVhal->mOnBinderDiedContexts.size();
370     }
371 
hasNoSubscriptions()372     bool hasNoSubscriptions() { return mVhal->mSubscriptionManager->isEmpty(); }
373 
setBinderAlive(bool isAlive)374     void setBinderAlive(bool isAlive) { mBinderLifecycleHandler->setAlive(isAlive); };
375 
getValuesTestCases(size_t size,GetValueRequests & requests,std::vector<GetValueResult> & expectedResults,std::vector<GetValueRequest> & expectedHardwareRequests)376     static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
377                                            std::vector<GetValueResult>& expectedResults,
378                                            std::vector<GetValueRequest>& expectedHardwareRequests) {
379         expectedHardwareRequests.clear();
380         for (size_t i = 0; i < size; i++) {
381             int64_t requestId = static_cast<int64_t>(i);
382             int32_t propId = testInt32VecProp(i);
383             expectedHardwareRequests.push_back(GetValueRequest{
384                     .prop =
385                             VehiclePropValue{
386                                     .prop = propId,
387                             },
388                     .requestId = requestId,
389             });
390             expectedResults.push_back(GetValueResult{
391                     .requestId = requestId,
392                     .status = StatusCode::OK,
393                     .prop =
394                             VehiclePropValue{
395                                     .prop = propId,
396                                     .value.int32Values = {1, 2, 3, 4},
397                             },
398             });
399         }
400 
401         requests.payloads = expectedHardwareRequests;
402         auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests);
403         if (!result.ok()) {
404             return result.error();
405         }
406         if (result.value() != nullptr) {
407             requests.sharedMemoryFd = std::move(*result.value());
408             requests.payloads.clear();
409         }
410         return {};
411     }
412 
setValuesTestCases(size_t size,SetValueRequests & requests,std::vector<SetValueResult> & expectedResults,std::vector<SetValueRequest> & expectedHardwareRequests)413     static Result<void> setValuesTestCases(size_t size, SetValueRequests& requests,
414                                            std::vector<SetValueResult>& expectedResults,
415                                            std::vector<SetValueRequest>& expectedHardwareRequests) {
416         expectedHardwareRequests.clear();
417         for (size_t i = 0; i < size; i++) {
418             int64_t requestId = static_cast<int64_t>(i);
419             int32_t propId = testInt32VecProp(i);
420             expectedHardwareRequests.push_back(SetValueRequest{
421                     .value =
422                             VehiclePropValue{
423                                     .prop = propId,
424                                     .value.int32Values = {1, 2, 3, 4},
425                             },
426                     .requestId = requestId,
427             });
428             expectedResults.push_back(SetValueResult{
429                     .requestId = requestId,
430                     .status = StatusCode::OK,
431             });
432         }
433 
434         requests.payloads = expectedHardwareRequests;
435         auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests);
436         if (!result.ok()) {
437             return result.error();
438         }
439         if (result.value() != nullptr) {
440             requests.payloads.clear();
441             requests.sharedMemoryFd = std::move(*result.value());
442             requests.payloads.clear();
443         }
444         return {};
445     }
446 
447   private:
448     class TestBinderLifecycleHandler final : public DefaultVehicleHal::BinderLifecycleInterface {
449       public:
linkToDeath(AIBinder *,AIBinder_DeathRecipient *,void *)450         binder_status_t linkToDeath(AIBinder*, AIBinder_DeathRecipient*, void*) override {
451             if (mIsAlive) {
452                 return STATUS_OK;
453             } else {
454                 return STATUS_FAILED_TRANSACTION;
455             }
456         }
457 
isAlive(const AIBinder *)458         bool isAlive(const AIBinder*) override { return mIsAlive; }
459 
setAlive(bool isAlive)460         void setAlive(bool isAlive) { mIsAlive = isAlive; }
461 
462       private:
463         bool mIsAlive = true;
464     };
465 
466     std::shared_ptr<DefaultVehicleHal> mVhal;
467     std::shared_ptr<IVehicle> mVhalClient;
468     MockVehicleHardware* mHardwarePtr;
469     std::shared_ptr<MockVehicleCallback> mCallback;
470     std::shared_ptr<IVehicleCallback> mCallbackClient;
471     SpAIBinder mBinder;
472     TestBinderLifecycleHandler* mBinderLifecycleHandler;
473 };
474 
TEST_F(DefaultVehicleHalTest,testGetAllPropConfigsSmall)475 TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
476     auto testConfigs = std::vector<VehiclePropConfig>({
477             VehiclePropConfig{
478                     .prop = 1,
479             },
480             VehiclePropConfig{
481                     .prop = 2,
482             },
483     });
484 
485     auto hardware = std::make_unique<MockVehicleHardware>();
486     hardware->setPropertyConfigs(testConfigs);
487     auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
488     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
489 
490     VehiclePropConfigs output;
491     auto status = client->getAllPropConfigs(&output);
492 
493     ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
494     ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
495 }
496 
TEST_F(DefaultVehicleHalTest,testGetAllPropConfigsLarge)497 TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
498     std::vector<VehiclePropConfig> testConfigs;
499     // 5000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
500     for (size_t i = 0; i < 5000; i++) {
501         testConfigs.push_back(VehiclePropConfig{
502                 .prop = static_cast<int32_t>(i),
503         });
504     }
505 
506     auto hardware = std::make_unique<MockVehicleHardware>();
507     hardware->setPropertyConfigs(testConfigs);
508     auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
509     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
510 
511     VehiclePropConfigs output;
512     auto status = client->getAllPropConfigs(&output);
513 
514     ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
515     ASSERT_TRUE(output.payloads.empty());
516     auto result = LargeParcelableBase::stableLargeParcelableToParcelable(output);
517     ASSERT_TRUE(result.ok()) << "failed to parse result shared memory file: "
518                              << result.error().message();
519     ASSERT_EQ(result.value().getObject()->payloads, testConfigs);
520 }
521 
TEST_F(DefaultVehicleHalTest,testGetPropConfigs)522 TEST_F(DefaultVehicleHalTest, testGetPropConfigs) {
523     auto testConfigs = std::vector<VehiclePropConfig>({
524             VehiclePropConfig{
525                     .prop = 1,
526             },
527             VehiclePropConfig{
528                     .prop = 2,
529             },
530     });
531 
532     auto hardware = std::make_unique<MockVehicleHardware>();
533     hardware->setPropertyConfigs(testConfigs);
534     auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
535     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
536 
537     VehiclePropConfigs output;
538     auto status = client->getPropConfigs(std::vector<int32_t>({1, 2}), &output);
539 
540     ASSERT_TRUE(status.isOk()) << "getPropConfigs failed: " << status.getMessage();
541     ASSERT_EQ(output.payloads, testConfigs);
542 }
543 
TEST_F(DefaultVehicleHalTest,testGetPropConfigsInvalidArg)544 TEST_F(DefaultVehicleHalTest, testGetPropConfigsInvalidArg) {
545     auto testConfigs = std::vector<VehiclePropConfig>({
546             VehiclePropConfig{
547                     .prop = 1,
548             },
549             VehiclePropConfig{
550                     .prop = 2,
551             },
552     });
553 
554     auto hardware = std::make_unique<MockVehicleHardware>();
555     hardware->setPropertyConfigs(testConfigs);
556     auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
557     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
558 
559     VehiclePropConfigs output;
560     auto status = client->getPropConfigs(std::vector<int32_t>({1, 2, 3}), &output);
561 
562     ASSERT_FALSE(status.isOk()) << "getPropConfigs must fail with invalid prop ID";
563     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
564 }
565 
TEST_F(DefaultVehicleHalTest,testGetValuesSmall)566 TEST_F(DefaultVehicleHalTest, testGetValuesSmall) {
567     GetValueRequests requests;
568     std::vector<GetValueResult> expectedResults;
569     std::vector<GetValueRequest> expectedHardwareRequests;
570 
571     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
572 
573     getHardware()->addGetValueResponses(expectedResults);
574 
575     auto status = getClient()->getValues(getCallbackClient(), requests);
576 
577     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
578 
579     EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests)
580             << "requests to hardware mismatch";
581 
582     auto maybeGetValueResults = getCallback()->nextGetValueResults();
583     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
584     EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
585     EXPECT_EQ(countClients(), static_cast<size_t>(1));
586 }
587 
TEST_F(DefaultVehicleHalTest,testGetValuesLarge)588 TEST_F(DefaultVehicleHalTest, testGetValuesLarge) {
589     GetValueRequests requests;
590     std::vector<GetValueResult> expectedResults;
591     std::vector<GetValueRequest> expectedHardwareRequests;
592 
593     ASSERT_TRUE(getValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok())
594             << "requests to hardware mismatch";
595 
596     getHardware()->addGetValueResponses(expectedResults);
597 
598     auto status = getClient()->getValues(getCallbackClient(), requests);
599 
600     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
601 
602     EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests);
603 
604     auto maybeGetValueResults = getCallback()->nextGetValueResults();
605     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
606     const GetValueResults& getValueResults = maybeGetValueResults.value();
607     ASSERT_TRUE(getValueResults.payloads.empty())
608             << "payload should be empty, shared memory file should be used";
609 
610     auto result = LargeParcelableBase::stableLargeParcelableToParcelable(getValueResults);
611     ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
612     ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch";
613     EXPECT_EQ(countClients(), static_cast<size_t>(1));
614 }
615 
TEST_F(DefaultVehicleHalTest,testGetValuesErrorFromHardware)616 TEST_F(DefaultVehicleHalTest, testGetValuesErrorFromHardware) {
617     GetValueRequests requests;
618     std::vector<GetValueResult> expectedResults;
619     std::vector<GetValueRequest> expectedHardwareRequests;
620 
621     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
622 
623     getHardware()->setStatus("getValues", StatusCode::INTERNAL_ERROR);
624 
625     auto status = getClient()->getValues(getCallbackClient(), requests);
626 
627     ASSERT_FALSE(status.isOk()) << "expect getValues to fail when hardware returns error";
628     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INTERNAL_ERROR));
629 }
630 
TEST_F(DefaultVehicleHalTest,testGetValuesInvalidLargeParcelableInput)631 TEST_F(DefaultVehicleHalTest, testGetValuesInvalidLargeParcelableInput) {
632     GetValueRequests requests;
633     requests.sharedMemoryFd = ScopedFileDescriptor(0);
634 
635     auto status = getClient()->getValues(getCallbackClient(), requests);
636 
637     ASSERT_FALSE(status.isOk()) << "expect getValues to fail when input parcelable is not valid";
638     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
639 }
640 
TEST_F(DefaultVehicleHalTest,testGetValuesNoReadPermission)641 TEST_F(DefaultVehicleHalTest, testGetValuesNoReadPermission) {
642     GetValueRequests requests = {
643             .sharedMemoryFd = {},
644             .payloads =
645                     {
646                             {
647                                     .requestId = 0,
648                                     .prop =
649                                             {
650                                                     .prop = WRITE_ONLY_PROP,
651                                             },
652                             },
653                     },
654     };
655 
656     auto status = getClient()->getValues(getCallbackClient(), requests);
657 
658     ASSERT_TRUE(status.isOk()) << "getValue with no read permission should return okay with error "
659                                   "returned from callback"
660                                << ", error: " << status.getMessage();
661     EXPECT_TRUE(getHardware()->nextGetValueRequests().empty()) << "expect no request to hardware";
662 
663     auto maybeResult = getCallback()->nextGetValueResults();
664     ASSERT_TRUE(maybeResult.has_value()) << "no results in callback";
665     EXPECT_EQ(maybeResult.value().payloads, std::vector<GetValueResult>({
666                                                     {
667                                                             .requestId = 0,
668                                                             .status = StatusCode::ACCESS_DENIED,
669                                                     },
670                                             }))
671             << "expect to get ACCESS_DENIED status if no read permission";
672 }
673 
TEST_F(DefaultVehicleHalTest,testGetValuesFinishBeforeTimeout)674 TEST_F(DefaultVehicleHalTest, testGetValuesFinishBeforeTimeout) {
675     // timeout: 1s
676     int64_t timeout = 1000000000;
677     setTimeout(timeout);
678 
679     GetValueRequests requests;
680     std::vector<GetValueResult> expectedResults;
681     std::vector<GetValueRequest> expectedHardwareRequests;
682 
683     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
684 
685     // The response would be returned after 0.01s.
686     getHardware()->setSleepTime(timeout / 100);
687     getHardware()->addGetValueResponses(expectedResults);
688 
689     auto status = getClient()->getValues(getCallbackClient(), requests);
690 
691     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
692 
693     ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout)) << "no results in callback";
694     auto maybeGetValueResults = getCallback()->nextGetValueResults();
695     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
696     EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
697     ASSERT_FALSE(getCallback()->nextGetValueResults().has_value()) << "more results than expected";
698 }
699 
TEST_F(DefaultVehicleHalTest,testGetValuesFinishAfterTimeout)700 TEST_F(DefaultVehicleHalTest, testGetValuesFinishAfterTimeout) {
701     // timeout: 0.01s
702     int64_t timeout = 10000000;
703     setTimeout(timeout);
704 
705     GetValueRequests requests;
706     std::vector<GetValueResult> expectedResults;
707     std::vector<GetValueRequest> expectedHardwareRequests;
708 
709     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
710 
711     // The response would be returned after 0.1s.
712     getHardware()->setSleepTime(timeout * 10);
713     getHardware()->addGetValueResponses(expectedResults);
714 
715     auto status = getClient()->getValues(getCallbackClient(), requests);
716 
717     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
718 
719     for (size_t i = 0; i < expectedResults.size(); i++) {
720         expectedResults[i] = {
721                 .requestId = expectedResults[i].requestId,
722                 .status = StatusCode::TRY_AGAIN,
723                 .prop = std::nullopt,
724         };
725     }
726 
727     ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout * 100))
728             << "no results in callback";
729     auto maybeGetValueResults = getCallback()->nextGetValueResults();
730     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
731     ASSERT_THAT(maybeGetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
732             << "results mismatch, expect TRY_AGAIN error.";
733     ASSERT_FALSE(getCallback()->nextGetValueResults().has_value()) << "more results than expected";
734 }
735 
TEST_F(DefaultVehicleHalTest,testGetValuesDuplicateRequestIdsInTwoRequests)736 TEST_F(DefaultVehicleHalTest, testGetValuesDuplicateRequestIdsInTwoRequests) {
737     // timeout: 0.1s
738     int64_t timeout = 100000000;
739     setTimeout(timeout);
740 
741     GetValueRequests requests;
742     std::vector<GetValueResult> expectedResults;
743     std::vector<GetValueRequest> expectedHardwareRequests;
744 
745     ASSERT_TRUE(getValuesTestCases(1, requests, expectedResults, expectedHardwareRequests).ok());
746 
747     getHardware()->setSleepTime(timeout * 2);
748     getHardware()->addGetValueResponses(expectedResults);
749 
750     auto status = getClient()->getValues(getCallbackClient(), requests);
751 
752     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
753 
754     // Use the same request ID again.
755     status = getClient()->getValues(getCallbackClient(), requests);
756 
757     ASSERT_FALSE(status.isOk())
758             << "Use the same request ID before the previous request finishes must fail";
759 
760     // Wait for the request to finish.
761     std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
762 }
763 
TEST_F(DefaultVehicleHalTest,testGetValuesDuplicateRequestIdsInOneRequest)764 TEST_F(DefaultVehicleHalTest, testGetValuesDuplicateRequestIdsInOneRequest) {
765     GetValueRequests requests = {.payloads = {
766                                          {
767                                                  .requestId = 0,
768                                                  .prop =
769                                                          VehiclePropValue{
770                                                                  .prop = testInt32VecProp(0),
771                                                          },
772                                          },
773                                          {
774                                                  .requestId = 0,
775                                                  .prop =
776                                                          VehiclePropValue{
777                                                                  .prop = testInt32VecProp(1),
778                                                          },
779                                          },
780                                  }};
781 
782     auto status = getClient()->getValues(getCallbackClient(), requests);
783 
784     ASSERT_FALSE(status.isOk()) << "duplicate Ids in one request must fail";
785 }
786 
TEST_F(DefaultVehicleHalTest,testGetValuesDuplicateRequestProps)787 TEST_F(DefaultVehicleHalTest, testGetValuesDuplicateRequestProps) {
788     GetValueRequests requests = {.payloads = {
789                                          {
790                                                  .requestId = 0,
791                                                  .prop =
792                                                          VehiclePropValue{
793                                                                  .prop = testInt32VecProp(0),
794                                                          },
795                                          },
796                                          {
797                                                  .requestId = 1,
798                                                  .prop =
799                                                          VehiclePropValue{
800                                                                  .prop = testInt32VecProp(0),
801                                                          },
802                                          },
803                                  }};
804 
805     auto status = getClient()->getValues(getCallbackClient(), requests);
806 
807     ASSERT_FALSE(status.isOk()) << "duplicate request properties in one request must fail";
808 }
809 
TEST_F(DefaultVehicleHalTest,testGetValuesNewClientDied)810 TEST_F(DefaultVehicleHalTest, testGetValuesNewClientDied) {
811     GetValueRequests requests;
812     std::vector<GetValueResult> expectedResults;
813     std::vector<GetValueRequest> expectedHardwareRequests;
814 
815     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
816 
817     getHardware()->addGetValueResponses(expectedResults);
818 
819     setBinderAlive(false);
820 
821     auto status = getClient()->getValues(getCallbackClient(), requests);
822 
823     ASSERT_FALSE(status.isOk()) << "getValues must fail if client died";
824     ASSERT_EQ(status.getExceptionCode(), EX_TRANSACTION_FAILED);
825     EXPECT_EQ(countClients(), static_cast<size_t>(0))
826             << "No client should be created if the client binder died";
827 }
828 
TEST_F(DefaultVehicleHalTest,testGetValuesExistingClientDied)829 TEST_F(DefaultVehicleHalTest, testGetValuesExistingClientDied) {
830     GetValueRequests requests;
831     std::vector<GetValueResult> expectedResults;
832     std::vector<GetValueRequest> expectedHardwareRequests;
833 
834     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
835 
836     getHardware()->addGetValueResponses(expectedResults);
837 
838     // Try a normal getValue request to cache a GetValueClient first.
839     auto status = getClient()->getValues(getCallbackClient(), requests);
840 
841     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
842     EXPECT_EQ(countClients(), static_cast<size_t>(1));
843 
844     // The client binder died before onBinderUnlinked clean up the GetValueClient.
845     setBinderAlive(false);
846 
847     status = getClient()->getValues(getCallbackClient(), requests);
848 
849     ASSERT_FALSE(status.isOk()) << "getValues must fail if client died";
850     ASSERT_EQ(status.getExceptionCode(), EX_TRANSACTION_FAILED);
851     // The client count should still be 1 but onBinderUnlinked will remove this later.
852     EXPECT_EQ(countClients(), static_cast<size_t>(1));
853 }
854 
TEST_F(DefaultVehicleHalTest,testSetValuesSmall)855 TEST_F(DefaultVehicleHalTest, testSetValuesSmall) {
856     SetValueRequests requests;
857     std::vector<SetValueResult> expectedResults;
858     std::vector<SetValueRequest> expectedHardwareRequests;
859 
860     ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
861 
862     getHardware()->addSetValueResponses(expectedResults);
863 
864     auto status = getClient()->setValues(getCallbackClient(), requests);
865 
866     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
867 
868     EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
869             << "requests to hardware mismatch";
870 
871     auto maybeSetValueResults = getCallback()->nextSetValueResults();
872     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
873     ASSERT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
874     EXPECT_EQ(countClients(), static_cast<size_t>(1));
875 }
876 
TEST_F(DefaultVehicleHalTest,testSetValuesLarge)877 TEST_F(DefaultVehicleHalTest, testSetValuesLarge) {
878     SetValueRequests requests;
879     std::vector<SetValueResult> expectedResults;
880     std::vector<SetValueRequest> expectedHardwareRequests;
881 
882     ASSERT_TRUE(setValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok());
883 
884     getHardware()->addSetValueResponses(expectedResults);
885 
886     auto status = getClient()->setValues(getCallbackClient(), requests);
887 
888     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
889 
890     EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
891             << "requests to hardware mismatch";
892 
893     auto maybeSetValueResults = getCallback()->nextSetValueResults();
894     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
895     const SetValueResults& setValueResults = maybeSetValueResults.value();
896     ASSERT_TRUE(setValueResults.payloads.empty())
897             << "payload should be empty, shared memory file should be used";
898 
899     auto result = LargeParcelableBase::stableLargeParcelableToParcelable(setValueResults);
900     ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
901     ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch";
902     EXPECT_EQ(countClients(), static_cast<size_t>(1));
903 }
904 
905 class SetValuesInvalidRequestTest
906     : public DefaultVehicleHalTest,
907       public testing::WithParamInterface<SetValuesInvalidRequestTestCase> {};
908 
909 INSTANTIATE_TEST_SUITE_P(
910         SetValuesInvalidRequestTests, SetValuesInvalidRequestTest,
911         testing::ValuesIn(getSetValuesInvalidRequestTestCases()),
__anon060c6f7d0202(const testing::TestParamInfo<SetValuesInvalidRequestTest::ParamType>& info) 912         [](const testing::TestParamInfo<SetValuesInvalidRequestTest::ParamType>& info) {
913             return info.param.name;
914         });
915 
TEST_P(SetValuesInvalidRequestTest,testSetValuesInvalidRequest)916 TEST_P(SetValuesInvalidRequestTest, testSetValuesInvalidRequest) {
917     SetValuesInvalidRequestTestCase tc = GetParam();
918     std::vector<SetValueResult> expectedHardwareResults{
919             SetValueResult{
920                     .requestId = 1,
921                     .status = StatusCode::OK,
922             },
923     };
924     getHardware()->addSetValueResponses(expectedHardwareResults);
925 
926     SetValueRequests requests;
927     SetValueRequest invalidRequest{
928             .requestId = 0,
929             .value = tc.request,
930     };
931     SetValueRequest normalRequest{.requestId = 1,
932                                   .value = {
933                                           .prop = testInt32VecProp(0),
934                                           .value.int32Values = {0},
935                                   }};
936     requests.payloads = {invalidRequest, normalRequest};
937     auto status = getClient()->setValues(getCallbackClient(), requests);
938 
939     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
940 
941     EXPECT_EQ(getHardware()->nextSetValueRequests(), std::vector<SetValueRequest>({normalRequest}))
942             << "requests to hardware mismatch";
943 
944     auto maybeSetValueResults = getCallback()->nextSetValueResults();
945     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
946     EXPECT_EQ(maybeSetValueResults.value().payloads, std::vector<SetValueResult>({
947                                                              {
948                                                                      .requestId = 0,
949                                                                      .status = tc.expectedStatus,
950                                                              },
951                                                      }))
952             << "invalid argument result mismatch";
953 
954     maybeSetValueResults = getCallback()->nextSetValueResults();
955     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results from hardware in callback";
956     EXPECT_EQ(maybeSetValueResults.value().payloads, expectedHardwareResults)
957             << "results from hardware mismatch";
958 }
959 
TEST_F(DefaultVehicleHalTest,testSetValuesFinishBeforeTimeout)960 TEST_F(DefaultVehicleHalTest, testSetValuesFinishBeforeTimeout) {
961     // timeout: 1s
962     int64_t timeout = 1000000000;
963     setTimeout(timeout);
964 
965     SetValueRequests requests;
966     std::vector<SetValueResult> expectedResults;
967     std::vector<SetValueRequest> expectedHardwareRequests;
968 
969     ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
970 
971     // The response would be returned after 0.01s.
972     getHardware()->setSleepTime(timeout / 100);
973     getHardware()->addSetValueResponses(expectedResults);
974 
975     auto status = getClient()->setValues(getCallbackClient(), requests);
976 
977     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
978 
979     ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout)) << "no set value results";
980     auto maybeSetValueResults = getCallback()->nextSetValueResults();
981     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
982     EXPECT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
983     ASSERT_FALSE(getCallback()->nextSetValueResults().has_value()) << "more results than expected";
984 }
985 
TEST_F(DefaultVehicleHalTest,testSetValuesFinishAfterTimeout)986 TEST_F(DefaultVehicleHalTest, testSetValuesFinishAfterTimeout) {
987     // timeout: 0.01s
988     int64_t timeout = 10000000;
989     setTimeout(timeout);
990 
991     SetValueRequests requests;
992     std::vector<SetValueResult> expectedResults;
993     std::vector<SetValueRequest> expectedHardwareRequests;
994 
995     ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
996 
997     // The response would be returned after 0.1s.
998     getHardware()->setSleepTime(timeout * 10);
999     getHardware()->addSetValueResponses(expectedResults);
1000 
1001     auto status = getClient()->setValues(getCallbackClient(), requests);
1002 
1003     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1004 
1005     for (size_t i = 0; i < expectedResults.size(); i++) {
1006         expectedResults[i] = {
1007                 .requestId = expectedResults[i].requestId,
1008                 .status = StatusCode::TRY_AGAIN,
1009         };
1010     }
1011 
1012     ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout * 100)) << "no set value results";
1013     auto maybeSetValueResults = getCallback()->nextSetValueResults();
1014     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
1015     ASSERT_THAT(maybeSetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
1016             << "results mismatch, expect TRY_AGAIN error.";
1017     ASSERT_FALSE(getCallback()->nextSetValueResults().has_value()) << "more results than expected";
1018 }
1019 
TEST_F(DefaultVehicleHalTest,testSetValuesDuplicateRequestIdsInTwoRequests)1020 TEST_F(DefaultVehicleHalTest, testSetValuesDuplicateRequestIdsInTwoRequests) {
1021     // timeout: 0.1s
1022     int64_t timeout = 100000000;
1023     setTimeout(timeout);
1024 
1025     SetValueRequests requests;
1026     std::vector<SetValueResult> expectedResults;
1027     std::vector<SetValueRequest> expectedHardwareRequests;
1028 
1029     ASSERT_TRUE(setValuesTestCases(1, requests, expectedResults, expectedHardwareRequests).ok());
1030 
1031     getHardware()->setSleepTime(timeout * 2);
1032     getHardware()->addSetValueResponses(expectedResults);
1033 
1034     auto status = getClient()->setValues(getCallbackClient(), requests);
1035 
1036     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1037 
1038     // Use the same request ID again.
1039     status = getClient()->setValues(getCallbackClient(), requests);
1040 
1041     ASSERT_FALSE(status.isOk())
1042             << "Use the same request ID before the previous request finishes must fail";
1043 
1044     // Wait for the request to finish.
1045     std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
1046 }
1047 
TEST_F(DefaultVehicleHalTest,testSetValuesDuplicateRequestIdsInOneRequest)1048 TEST_F(DefaultVehicleHalTest, testSetValuesDuplicateRequestIdsInOneRequest) {
1049     SetValueRequests requests = {.payloads = {
1050                                          {
1051                                                  .requestId = 0,
1052                                                  .value =
1053                                                          VehiclePropValue{
1054                                                                  .prop = testInt32VecProp(0),
1055                                                                  .value.int32Values = {0},
1056                                                          },
1057                                          },
1058                                          {
1059                                                  .requestId = 0,
1060                                                  .value =
1061                                                          VehiclePropValue{
1062                                                                  .prop = testInt32VecProp(1),
1063                                                                  .value.int32Values = {0},
1064                                                          },
1065                                          },
1066                                  }};
1067 
1068     auto status = getClient()->setValues(getCallbackClient(), requests);
1069 
1070     ASSERT_FALSE(status.isOk()) << "duplicate Ids in one request must fail";
1071 }
1072 
TEST_F(DefaultVehicleHalTest,testSetValuesDuplicateRequestProps)1073 TEST_F(DefaultVehicleHalTest, testSetValuesDuplicateRequestProps) {
1074     SetValueRequests requests = {.payloads = {
1075                                          {
1076                                                  .requestId = 0,
1077                                                  .value =
1078                                                          VehiclePropValue{
1079                                                                  .prop = testInt32VecProp(0),
1080                                                                  .value.int32Values = {0},
1081                                                          },
1082                                          },
1083                                          {
1084                                                  .requestId = 1,
1085                                                  .value =
1086                                                          VehiclePropValue{
1087                                                                  .prop = testInt32VecProp(0),
1088                                                                  .value.int32Values = {0},
1089                                                          },
1090                                          },
1091                                  }};
1092 
1093     auto status = getClient()->setValues(getCallbackClient(), requests);
1094 
1095     ASSERT_FALSE(status.isOk()) << "duplicate request properties in one request must fail";
1096 }
1097 
TEST_F(DefaultVehicleHalTest,testSubscribeUnsubscribe)1098 TEST_F(DefaultVehicleHalTest, testSubscribeUnsubscribe) {
1099     std::vector<SubscribeOptions> options = {
1100             {
1101                     .propId = GLOBAL_ON_CHANGE_PROP,
1102             },
1103     };
1104 
1105     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1106 
1107     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1108 
1109     status = getClient()->unsubscribe(getCallbackClient(),
1110                                       std::vector<int32_t>({GLOBAL_ON_CHANGE_PROP}));
1111 
1112     ASSERT_TRUE(status.isOk()) << "unsubscribe failed: " << status.getMessage();
1113 }
1114 
TEST_F(DefaultVehicleHalTest,testSubscribeGlobalOnChangeNormal)1115 TEST_F(DefaultVehicleHalTest, testSubscribeGlobalOnChangeNormal) {
1116     std::vector<SubscribeOptions> options = {
1117             {
1118                     .propId = GLOBAL_ON_CHANGE_PROP,
1119             },
1120     };
1121 
1122     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1123 
1124     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1125 
1126     VehiclePropValue testValue{
1127             .prop = GLOBAL_ON_CHANGE_PROP,
1128             .value.int32Values = {0},
1129     };
1130     SetValueRequests setValueRequests = {
1131             .payloads =
1132                     {
1133                             SetValueRequest{
1134                                     .requestId = 0,
1135                                     .value = testValue,
1136                             },
1137                     },
1138     };
1139     std::vector<SetValueResult> setValueResults = {{
1140             .requestId = 0,
1141             .status = StatusCode::OK,
1142     }};
1143 
1144     // Set the value to trigger a property change event.
1145     getHardware()->addSetValueResponses(setValueResults);
1146     status = getClient()->setValues(getCallbackClient(), setValueRequests);
1147 
1148     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1149 
1150     auto maybeResults = getCallback()->nextOnPropertyEventResults();
1151     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
1152     ASSERT_THAT(maybeResults.value().payloads, UnorderedElementsAre(testValue))
1153             << "results mismatch, expect on change event for the updated value";
1154     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
1155             << "more results than expected";
1156     EXPECT_EQ(countClients(), static_cast<size_t>(2))
1157             << "expect 2 clients, 1 subscribe client and 1 setvalue client";
1158 }
1159 
TEST_F(DefaultVehicleHalTest,testSubscribeGlobalOnchangeUnrelatedEventIgnored)1160 TEST_F(DefaultVehicleHalTest, testSubscribeGlobalOnchangeUnrelatedEventIgnored) {
1161     std::vector<SubscribeOptions> options = {
1162             {
1163                     .propId = GLOBAL_ON_CHANGE_PROP,
1164             },
1165     };
1166 
1167     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1168 
1169     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1170 
1171     VehiclePropValue testValue{
1172             .prop = GLOBAL_CONTINUOUS_PROP,
1173             .value.int32Values = {0},
1174     };
1175 
1176     // Set the value to trigger a property change event. This event should be ignored because we
1177     // have not subscribed to it.
1178     getHardware()->addSetValueResponses({{
1179             .requestId = 0,
1180             .status = StatusCode::OK,
1181     }});
1182     status = getClient()->setValues(getCallbackClient(),
1183                                     {
1184                                             .payloads =
1185                                                     {
1186                                                             SetValueRequest{
1187                                                                     .requestId = 0,
1188                                                                     .value = testValue,
1189                                                             },
1190                                                     },
1191                                     });
1192 
1193     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1194 
1195     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
1196             << "must receive no property update event if the property is not subscribed";
1197 }
1198 
TEST_F(DefaultVehicleHalTest,testSubscribeAreaOnChange)1199 TEST_F(DefaultVehicleHalTest, testSubscribeAreaOnChange) {
1200     int testAreaId = toInt(VehicleAreaWindow::ROW_1_LEFT);
1201     std::vector<SubscribeOptions> options = {
1202             {
1203                     .propId = AREA_ON_CHANGE_PROP,
1204                     .areaIds = {testAreaId},
1205             },
1206     };
1207 
1208     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1209 
1210     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1211 
1212     VehiclePropValue testValue{
1213             .prop = AREA_ON_CHANGE_PROP,
1214             .areaId = testAreaId,
1215             .value.int32Values = {0},
1216     };
1217 
1218     // Set the value to trigger a property change event.
1219     getHardware()->addSetValueResponses({{
1220             .requestId = 0,
1221             .status = StatusCode::OK,
1222     }});
1223     status = getClient()->setValues(getCallbackClient(),
1224                                     {
1225                                             .payloads =
1226                                                     {
1227                                                             SetValueRequest{
1228                                                                     .requestId = 0,
1229                                                                     .value = testValue,
1230                                                             },
1231                                                     },
1232                                     });
1233 
1234     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1235 
1236     auto maybeResults = getCallback()->nextOnPropertyEventResults();
1237     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
1238     ASSERT_THAT(maybeResults.value().payloads, UnorderedElementsAre(testValue))
1239             << "results mismatch, expect on change event for the updated value";
1240     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
1241             << "more results than expected";
1242 }
1243 
TEST_F(DefaultVehicleHalTest,testSubscribeAreaOnChangeAllAreas)1244 TEST_F(DefaultVehicleHalTest, testSubscribeAreaOnChangeAllAreas) {
1245     std::vector<SubscribeOptions> options = {
1246             {
1247                     .propId = AREA_ON_CHANGE_PROP,
1248                     // No areaIds means subscribing to all area IDs.
1249                     .areaIds = {},
1250             },
1251     };
1252 
1253     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1254 
1255     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1256 
1257     VehiclePropValue testValue1{
1258             .prop = AREA_ON_CHANGE_PROP,
1259             .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
1260             .value.int32Values = {0},
1261     };
1262     VehiclePropValue testValue2{
1263             .prop = AREA_ON_CHANGE_PROP,
1264             .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
1265             .value.int32Values = {0},
1266     };
1267 
1268     // Set the values to trigger property change events for two areas.
1269     getHardware()->addSetValueResponses({{
1270                                                  .requestId = 0,
1271                                                  .status = StatusCode::OK,
1272                                          },
1273                                          {
1274                                                  .requestId = 1,
1275                                                  .status = StatusCode::OK,
1276                                          }});
1277     status = getClient()->setValues(getCallbackClient(),
1278                                     {
1279                                             .payloads =
1280                                                     {
1281                                                             SetValueRequest{
1282                                                                     .requestId = 0,
1283                                                                     .value = testValue1,
1284                                                             },
1285                                                             SetValueRequest{
1286                                                                     .requestId = 1,
1287                                                                     .value = testValue2,
1288                                                             },
1289                                                     },
1290                                     });
1291 
1292     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1293 
1294     auto maybeResults = getCallback()->nextOnPropertyEventResults();
1295     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
1296     ASSERT_THAT(maybeResults.value().payloads, UnorderedElementsAre(testValue1, testValue2))
1297             << "results mismatch, expect two on-change events for all updated areas";
1298     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
1299             << "more results than expected";
1300 }
1301 
TEST_F(DefaultVehicleHalTest,testSubscribeGlobalContinuous)1302 TEST_F(DefaultVehicleHalTest, testSubscribeGlobalContinuous) {
1303     VehiclePropValue testValue{
1304             .prop = GLOBAL_CONTINUOUS_PROP,
1305     };
1306 
1307     std::vector<SubscribeOptions> options = {
1308             {
1309                     .propId = GLOBAL_CONTINUOUS_PROP,
1310                     .sampleRate = 20.0,
1311             },
1312     };
1313 
1314     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1315 
1316     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1317 
1318     // Sleep for 1s, which should generate ~20 events.
1319     std::this_thread::sleep_for(std::chrono::seconds(1));
1320 
1321     // Should trigger about 20 times, check for at least 15 events to be safe.
1322     for (size_t i = 0; i < 15; i++) {
1323         auto maybeResults = getCallback()->nextOnPropertyEventResults();
1324         ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
1325         ASSERT_THAT(maybeResults.value().payloads, UnorderedElementsAre(testValue))
1326                 << "results mismatch, expect to get the updated value";
1327     }
1328     EXPECT_EQ(countClients(), static_cast<size_t>(1));
1329 }
1330 
TEST_F(DefaultVehicleHalTest,testSubscribeGlobalContinuousRateOutOfRange)1331 TEST_F(DefaultVehicleHalTest, testSubscribeGlobalContinuousRateOutOfRange) {
1332     // The maxSampleRate is 100, so the sample rate should be the default max 100.
1333     std::vector<SubscribeOptions> options = {
1334             {
1335                     .propId = GLOBAL_CONTINUOUS_PROP,
1336                     .sampleRate = 1000.0,
1337             },
1338     };
1339 
1340     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1341 
1342     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1343 
1344     // Sleep for 1s, which should generate ~100 events.
1345     std::this_thread::sleep_for(std::chrono::seconds(1));
1346 
1347     size_t eventCount = getCallback()->countOnPropertyEventResults();
1348     ASSERT_GE(eventCount, 50u) << "expect at least 50 events to be generated";
1349     ASSERT_LE(eventCount, 150u) << "expect no more than 150 events to be generated";
1350 
1351     EXPECT_EQ(countClients(), static_cast<size_t>(1));
1352 }
1353 
TEST_F(DefaultVehicleHalTest,testSubscribeAreaContinuous)1354 TEST_F(DefaultVehicleHalTest, testSubscribeAreaContinuous) {
1355     std::vector<SubscribeOptions> options = {
1356             {
1357                     .propId = AREA_CONTINUOUS_PROP,
1358                     .sampleRate = 20.0,
1359                     .areaIds = {toInt(VehicleAreaWindow::ROW_1_LEFT)},
1360             },
1361             {
1362                     .propId = AREA_CONTINUOUS_PROP,
1363                     .sampleRate = 10.0,
1364                     .areaIds = {toInt(VehicleAreaWindow::ROW_1_RIGHT)},
1365             },
1366     };
1367 
1368     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1369 
1370     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1371 
1372     // Sleep for 1s, which should generate ~20 events.
1373     std::this_thread::sleep_for(std::chrono::seconds(1));
1374 
1375     getClient()->unsubscribe(getCallbackClient(), std::vector<int32_t>({AREA_CONTINUOUS_PROP}));
1376 
1377     std::vector<VehiclePropValue> events;
1378     while (true) {
1379         auto maybeResults = getCallback()->nextOnPropertyEventResults();
1380         if (!maybeResults.has_value()) {
1381             break;
1382         }
1383         for (const auto& value : maybeResults.value().payloads) {
1384             events.push_back(value);
1385         }
1386     }
1387 
1388     size_t leftCount = 0;
1389     size_t rightCount = 0;
1390 
1391     for (const auto& event : events) {
1392         ASSERT_EQ(event.prop, AREA_CONTINUOUS_PROP);
1393         if (event.areaId == toInt(VehicleAreaWindow::ROW_1_LEFT)) {
1394             leftCount++;
1395             continue;
1396         }
1397         rightCount++;
1398     }
1399 
1400     // Should trigger about 20 times, check for at least 15 events to be safe.
1401     ASSERT_GE(leftCount, static_cast<size_t>(15));
1402     // Should trigger about 10 times, check for at least 5 events to be safe.
1403     ASSERT_GE(rightCount, static_cast<size_t>(5));
1404 }
1405 
TEST_F(DefaultVehicleHalTest,testUnsubscribeOnChange)1406 TEST_F(DefaultVehicleHalTest, testUnsubscribeOnChange) {
1407     std::vector<SubscribeOptions> options = {
1408             {
1409                     .propId = GLOBAL_ON_CHANGE_PROP,
1410             },
1411     };
1412 
1413     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1414 
1415     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1416 
1417     status = getClient()->unsubscribe(getCallbackClient(),
1418                                       std::vector<int32_t>({GLOBAL_ON_CHANGE_PROP}));
1419 
1420     ASSERT_TRUE(status.isOk()) << "unsubscribe failed: " << status.getMessage();
1421 
1422     VehiclePropValue testValue{
1423             .prop = GLOBAL_ON_CHANGE_PROP,
1424             .value.int32Values = {0},
1425     };
1426 
1427     // Set the value to trigger a property change event.
1428     getHardware()->addSetValueResponses({{
1429             .requestId = 0,
1430             .status = StatusCode::OK,
1431     }});
1432     status = getClient()->setValues(getCallbackClient(),
1433                                     {
1434                                             .payloads =
1435                                                     {
1436                                                             SetValueRequest{
1437                                                                     .requestId = 0,
1438                                                                     .value = testValue,
1439                                                             },
1440                                                     },
1441                                     });
1442 
1443     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
1444 
1445     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
1446             << "No property event should be generated after unsubscription";
1447 }
1448 
TEST_F(DefaultVehicleHalTest,testUnsubscribeContinuous)1449 TEST_F(DefaultVehicleHalTest, testUnsubscribeContinuous) {
1450     std::vector<SubscribeOptions> options = {
1451             {
1452                     .propId = GLOBAL_CONTINUOUS_PROP,
1453                     .sampleRate = 100.0,
1454             },
1455     };
1456 
1457     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1458 
1459     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1460 
1461     status = getClient()->unsubscribe(getCallbackClient(),
1462                                       std::vector<int32_t>({GLOBAL_CONTINUOUS_PROP}));
1463 
1464     ASSERT_TRUE(status.isOk()) << "unsubscribe failed: " << status.getMessage();
1465 
1466     // Wait for the last events to come.
1467     std::this_thread::sleep_for(std::chrono::milliseconds(100));
1468 
1469     // Clear existing events.
1470     while (getCallback()->nextOnPropertyEventResults().has_value()) {
1471         // Do nothing.
1472     }
1473 
1474     // Wait for a while, make sure no new events are generated. If still subscribed, this should
1475     // generate around 10 events.
1476     std::this_thread::sleep_for(std::chrono::milliseconds(100));
1477 
1478     ASSERT_EQ(getCallback()->countOnPropertyEventResults(), 0u)
1479             << "Property event generation must stop after unsubscription";
1480 }
1481 
1482 class SubscribeInvalidOptionsTest
1483     : public DefaultVehicleHalTest,
1484       public testing::WithParamInterface<SubscribeInvalidOptionsTestCase> {};
1485 
1486 INSTANTIATE_TEST_SUITE_P(
1487         SubscribeInvalidOptionsTests, SubscribeInvalidOptionsTest,
1488         testing::ValuesIn(getSubscribeInvalidOptionsTestCases()),
__anon060c6f7d0302(const testing::TestParamInfo<SubscribeInvalidOptionsTest::ParamType>& info) 1489         [](const testing::TestParamInfo<SubscribeInvalidOptionsTest::ParamType>& info) {
1490             return info.param.name;
1491         });
1492 
TEST_P(SubscribeInvalidOptionsTest,testSubscribeInvalidOptions)1493 TEST_P(SubscribeInvalidOptionsTest, testSubscribeInvalidOptions) {
1494     std::vector<SubscribeOptions> options = {GetParam().option};
1495 
1496     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1497 
1498     ASSERT_FALSE(status.isOk()) << "invalid subscribe options must fail";
1499     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
1500 }
1501 
TEST_F(DefaultVehicleHalTest,testSubscribeNoReadPermission)1502 TEST_F(DefaultVehicleHalTest, testSubscribeNoReadPermission) {
1503     std::vector<SubscribeOptions> options = {{
1504             .propId = WRITE_ONLY_PROP,
1505     }};
1506 
1507     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1508 
1509     ASSERT_FALSE(status.isOk()) << "subscribe to a write-only property must fail";
1510     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::ACCESS_DENIED));
1511 }
1512 
TEST_F(DefaultVehicleHalTest,testUnsubscribeFailure)1513 TEST_F(DefaultVehicleHalTest, testUnsubscribeFailure) {
1514     auto status = getClient()->unsubscribe(getCallbackClient(),
1515                                            std::vector<int32_t>({GLOBAL_ON_CHANGE_PROP}));
1516 
1517     ASSERT_FALSE(status.isOk()) << "unsubscribe to a not-subscribed property must fail";
1518     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
1519 }
1520 
TEST_F(DefaultVehicleHalTest,testHeartbeatEvent)1521 TEST_F(DefaultVehicleHalTest, testHeartbeatEvent) {
1522     std::vector<SubscribeOptions> options = {{
1523             .propId = toInt(VehicleProperty::VHAL_HEARTBEAT),
1524     }};
1525     int64_t currentTime = uptimeMillis();
1526     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1527 
1528     ASSERT_TRUE(status.isOk()) << "unable to subscribe to heartbeat event: " << status.getMessage();
1529 
1530     // We send out a heartbeat event every 3s, so sleep for 3s.
1531     std::this_thread::sleep_for(std::chrono::seconds(3));
1532 
1533     auto maybeResults = getCallback()->nextOnPropertyEventResults();
1534     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
1535     ASSERT_EQ(maybeResults.value().payloads.size(), static_cast<size_t>(1));
1536     VehiclePropValue gotValue = maybeResults.value().payloads[0];
1537     ASSERT_EQ(gotValue.prop, toInt(VehicleProperty::VHAL_HEARTBEAT));
1538     ASSERT_EQ(gotValue.value.int64Values.size(), static_cast<size_t>(1));
1539     ASSERT_GE(gotValue.value.int64Values[0], currentTime)
1540             << "expect to get the latest timestamp with the heartbeat event";
1541 }
1542 
TEST_F(DefaultVehicleHalTest,testOnBinderDiedUnlinked)1543 TEST_F(DefaultVehicleHalTest, testOnBinderDiedUnlinked) {
1544     // Set responses for all the hardware getValues requests.
1545     getHardware()->setGetValueResponder(
1546             [](std::shared_ptr<const IVehicleHardware::GetValuesCallback> callback,
1547                const std::vector<GetValueRequest>& requests) {
1548                 std::vector<GetValueResult> results;
1549                 for (auto& request : requests) {
1550                     VehiclePropValue prop = request.prop;
1551                     prop.value.int32Values = {0};
1552                     results.push_back({
1553                             .requestId = request.requestId,
1554                             .status = StatusCode::OK,
1555                             .prop = prop,
1556                     });
1557                 }
1558                 (*callback)(results);
1559                 return StatusCode::OK;
1560             });
1561     std::vector<SubscribeOptions> options = {
1562             {
1563                     .propId = GLOBAL_CONTINUOUS_PROP,
1564                     .sampleRate = 20.0,
1565             },
1566     };
1567     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1568     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1569     // Sleep for 100ms so that the subscriptionClient gets created because we would at least try to
1570     // get value once.
1571     std::this_thread::sleep_for(std::chrono::milliseconds(100));
1572 
1573     // Issue another getValue request on the same client.
1574     GetValueRequests requests;
1575     std::vector<GetValueResult> expectedResults;
1576     std::vector<GetValueRequest> expectedHardwareRequests;
1577     ASSERT_TRUE(getValuesTestCases(1, requests, expectedResults, expectedHardwareRequests).ok());
1578     getHardware()->addGetValueResponses(expectedResults);
1579     status = getClient()->getValues(getCallbackClient(), requests);
1580     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
1581 
1582     ASSERT_EQ(countOnBinderDiedContexts(), static_cast<size_t>(1))
1583             << "expect one OnBinderDied context when one client is registered";
1584 
1585     // Get the death recipient cookie for our callback that would be used in onBinderDied and
1586     // onBinderUnlinked.
1587     AIBinder* clientId = getCallbackClient()->asBinder().get();
1588     void* context = getOnBinderDiedContexts(clientId);
1589 
1590     onBinderDied(context);
1591 
1592     // Sleep for 100ms between checks.
1593     int64_t sleep = 100;
1594     // Timeout: 10s.
1595     int64_t timeout = 10'000'000'000;
1596     int64_t stopTime = elapsedRealtimeNano() + timeout;
1597     // Wait until the onBinderDied event is handled.
1598     while (countClients() != 0u && elapsedRealtimeNano() <= stopTime) {
1599         std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
1600     }
1601 
1602     ASSERT_EQ(countClients(), static_cast<size_t>(0))
1603             << "expect all clients to be removed when binder died";
1604     ASSERT_TRUE(hasNoSubscriptions()) << "expect no subscriptions when binder died";
1605 
1606     onBinderUnlinked(context);
1607 
1608     stopTime = elapsedRealtimeNano() + timeout;
1609     // Wait until the onBinderUnlinked event is handled.
1610     while (countOnBinderDiedContexts() != 0u && elapsedRealtimeNano() <= stopTime) {
1611         std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
1612     }
1613 
1614     ASSERT_EQ(countOnBinderDiedContexts(), static_cast<size_t>(0))
1615             << "expect OnBinderDied context to be deleted when binder is unlinked";
1616 }
1617 
TEST_F(DefaultVehicleHalTest,testDumpCallerShouldDump)1618 TEST_F(DefaultVehicleHalTest, testDumpCallerShouldDump) {
1619     std::string buffer = "Dump from hardware";
1620     getHardware()->setDumpResult({
1621             .callerShouldDumpState = true,
1622             .buffer = buffer,
1623     });
1624     int fd = memfd_create("memfile", 0);
1625     getClient()->dump(fd, nullptr, 0);
1626 
1627     lseek(fd, 0, SEEK_SET);
1628     char buf[10240] = {};
1629     read(fd, buf, sizeof(buf));
1630     close(fd);
1631 
1632     std::string msg(buf);
1633 
1634     ASSERT_THAT(msg, ContainsRegex(buffer + "\nVehicle HAL State: \n"));
1635 }
1636 
TEST_F(DefaultVehicleHalTest,testDumpCallerShouldNotDump)1637 TEST_F(DefaultVehicleHalTest, testDumpCallerShouldNotDump) {
1638     std::string buffer = "Dump from hardware";
1639     getHardware()->setDumpResult({
1640             .callerShouldDumpState = false,
1641             .buffer = buffer,
1642     });
1643     int fd = memfd_create("memfile", 0);
1644     getClient()->dump(fd, nullptr, 0);
1645 
1646     lseek(fd, 0, SEEK_SET);
1647     char buf[10240] = {};
1648     read(fd, buf, sizeof(buf));
1649     close(fd);
1650 
1651     std::string msg(buf);
1652 
1653     ASSERT_THAT(msg, ContainsRegex(buffer));
1654     ASSERT_EQ(msg.find("Vehicle HAL State: "), std::string::npos);
1655 }
1656 
TEST_F(DefaultVehicleHalTest,testOnPropertySetErrorEvent)1657 TEST_F(DefaultVehicleHalTest, testOnPropertySetErrorEvent) {
1658     std::vector<SubscribeOptions> options = {
1659             {
1660                     .propId = GLOBAL_ON_CHANGE_PROP,
1661                     .areaIds = {0},
1662             },
1663             {
1664                     .propId = GLOBAL_CONTINUOUS_PROP,
1665                     .areaIds = {0},
1666                     .sampleRate = 1,
1667             },
1668     };
1669     auto status = getClient()->subscribe(getCallbackClient(), options, 0);
1670     ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
1671     std::vector<SetValueErrorEvent> errorEvents = {
1672             {
1673                     .propId = GLOBAL_ON_CHANGE_PROP,
1674                     .areaId = 0,
1675                     .errorCode = StatusCode::INTERNAL_ERROR,
1676             },
1677             {
1678                     .propId = GLOBAL_ON_CHANGE_PROP,
1679                     .areaId = 0,
1680                     .errorCode = StatusCode::ACCESS_DENIED,
1681             },
1682             {
1683                     .propId = GLOBAL_CONTINUOUS_PROP,
1684                     .areaId = 0,
1685                     .errorCode = StatusCode::INVALID_ARG,
1686             },
1687     };
1688     std::vector<VehiclePropError> expectedResults = {
1689             {
1690                     .propId = GLOBAL_ON_CHANGE_PROP,
1691                     .areaId = 0,
1692                     .errorCode = StatusCode::INTERNAL_ERROR,
1693             },
1694             {
1695                     .propId = GLOBAL_ON_CHANGE_PROP,
1696                     .areaId = 0,
1697                     .errorCode = StatusCode::ACCESS_DENIED,
1698             },
1699             {
1700                     .propId = GLOBAL_CONTINUOUS_PROP,
1701                     .areaId = 0,
1702                     .errorCode = StatusCode::INVALID_ARG,
1703             },
1704     };
1705     getHardware()->sendOnPropertySetErrorEvent(errorEvents);
1706 
1707     ASSERT_EQ(getCallback()->countOnPropertySetErrorResults(), 1u);
1708     auto maybeVehiclePropErrors = getCallback()->nextOnPropertySetErrorResults();
1709     ASSERT_TRUE(maybeVehiclePropErrors.has_value());
1710     const auto& vehiclePropErrors = maybeVehiclePropErrors.value();
1711     ASSERT_THAT(vehiclePropErrors.payloads, UnorderedElementsAreArray(expectedResults));
1712 }
1713 
1714 }  // namespace vehicle
1715 }  // namespace automotive
1716 }  // namespace hardware
1717 }  // namespace android
1718