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