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 <android-base/file.h>
18 #include <android/hardware/automotive/vehicle/2.0/types.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <sys/mman.h>
22 #include <vhal_v2_0/ConcurrentQueue.h>
23 #include <vhal_v2_0/DefaultConfig.h>
24 #include <vhal_v2_0/DefaultVehicleConnector.h>
25 #include <vhal_v2_0/DefaultVehicleHal.h>
26 #include <vhal_v2_0/PropertyUtils.h>
27 #include <vhal_v2_0/VehicleObjectPool.h>
28 #include <vhal_v2_0/VehiclePropertyStore.h>
29 
30 namespace android {
31 namespace hardware {
32 namespace automotive {
33 namespace vehicle {
34 namespace V2_0 {
35 namespace impl {
36 
37 class DefaultVhalImplTestHelper {
38   public:
DefaultVhalImplTestHelper(DefaultVehicleHalServer * server)39     DefaultVhalImplTestHelper(DefaultVehicleHalServer* server) { mServer = server; }
40 
overrideProperties(const char * overrideDir)41     void overrideProperties(const char* overrideDir) {
42         mServer->overrideProperties(overrideDir);
43     }
44 
45   private:
46     DefaultVehicleHalServer* mServer;
47 };
48 
49 }  // namespace impl
50 }  // namespace V2_0
51 }  // namespace vehicle
52 }  // namespace automotive
53 }  // namespace hardware
54 }  // namespace android
55 
56 namespace {
57 
58 using ::android::hardware::hidl_handle;
59 using ::android::hardware::hidl_string;
60 using ::android::hardware::hidl_vec;
61 using ::android::hardware::automotive::vehicle::V2_0::FuelType;
62 using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
63 using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
64 using ::android::hardware::automotive::vehicle::V2_0::VehicleHwKeyInputAction;
65 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
66 using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
67 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStatus;
68 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
69 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
70 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
71 using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleConnector;
72 using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleHal;
73 using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVhalImplTestHelper;
74 using ::android::hardware::automotive::vehicle::V2_0::impl::DOOR_1_LEFT;
75 using ::android::hardware::automotive::vehicle::V2_0::impl::DOOR_1_RIGHT;
76 using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_ALL;
77 using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_LEFT;
78 using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_RIGHT;
79 using ::android::hardware::automotive::vehicle::V2_0::impl::kMixedTypePropertyForTest;
80 using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME;
81 using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_CLEAR;
82 using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_INFO;
83 using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_LIVE_FRAME;
84 
85 using ::testing::HasSubstr;
86 
87 using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
88 
89 // The maximum length of property ID in string.
90 const size_t MAX_PROP_ID_LENGTH = 100;
91 
92 class DefaultVhalImplTest : public ::testing::Test {
93   public:
~DefaultVhalImplTest()94     ~DefaultVhalImplTest() {
95         mEventQueue.deactivate();
96         mHeartBeatQueue.deactivate();
97         // Destroy mHal before destroying its dependencies.
98         mHal.reset();
99         mConnector.reset();
100         mPropStore.reset();
101     }
102 
103   protected:
SetUp()104     void SetUp() override {
105         mPropStore.reset(new VehiclePropertyStore);
106         mConnector.reset(new DefaultVehicleConnector);
107         mConnector->setValuePool(&mValueObjectPool);
108         mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
109         initHal();
110     }
111 
initHal()112     void initHal() {
113         mHal->init(&mValueObjectPool,
114                    std::bind(&DefaultVhalImplTest::onHalEvent, this, std::placeholders::_1),
115                    std::bind(&DefaultVhalImplTest::onHalPropertySetError, this,
116                              std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
117     }
118 
119   protected:
120     std::unique_ptr<DefaultVehicleHal> mHal;
121     std::unique_ptr<DefaultVehicleConnector> mConnector;
122     std::unique_ptr<VehiclePropertyStore> mPropStore;
123     VehiclePropValuePool mValueObjectPool;
124     android::ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
125     android::ConcurrentQueue<VehiclePropValuePtr> mHeartBeatQueue;
126 
127     // Wait until receive enough events in receivedEvents.
waitForEvents(std::vector<VehiclePropValuePtr> * receivedEvents,size_t count)128     void waitForEvents(std::vector<VehiclePropValuePtr>* receivedEvents, size_t count) {
129         while (receivedEvents->size() < count) {
130             mEventQueue.waitForItems();
131             auto newEvents = mEventQueue.flush();
132             for (size_t i = 0; i < newEvents.size(); i++) {
133                 receivedEvents->push_back(std::move(newEvents[i]));
134             }
135         }
136     }
137 
138   private:
onHalEvent(VehiclePropValuePtr v)139     void onHalEvent(VehiclePropValuePtr v) {
140         if (v->prop != toInt(VehicleProperty::VHAL_HEARTBEAT)) {
141             // Ignore heartbeat properties.
142             mEventQueue.push(std::move(v));
143         } else {
144             mHeartBeatQueue.push(std::move(v));
145         }
146     }
147 
onHalPropertySetError(StatusCode,int32_t,int32_t)148     void onHalPropertySetError(StatusCode /*errorCode*/, int32_t /*property*/, int32_t /*areaId*/) {
149     }
150 };
151 
TEST_F(DefaultVhalImplTest,testListProperties)152 TEST_F(DefaultVhalImplTest, testListProperties) {
153     std::vector<VehiclePropConfig> configs = mHal->listProperties();
154 
155     EXPECT_EQ((size_t)124, configs.size());
156 }
157 
TEST_F(DefaultVhalImplTest,testGetDefaultPropertyFloat)158 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
159     VehiclePropValue value;
160     StatusCode status;
161     value.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
162 
163     auto gotValue = mHal->get(value, &status);
164 
165     EXPECT_EQ(StatusCode::OK, status);
166     ASSERT_EQ((unsigned int)1, gotValue->value.floatValues.size());
167     EXPECT_EQ(15000.0f, gotValue->value.floatValues[0]);
168 }
169 
TEST_F(DefaultVhalImplTest,testGetDefaultPropertyEnum)170 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyEnum) {
171     VehiclePropValue value;
172     StatusCode status;
173     value.prop = toInt(VehicleProperty::INFO_FUEL_TYPE);
174 
175     auto gotValue = mHal->get(value, &status);
176 
177     EXPECT_EQ(StatusCode::OK, status);
178     ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
179     EXPECT_EQ((int)FuelType::FUEL_TYPE_UNLEADED, gotValue->value.int32Values[0]);
180 }
181 
TEST_F(DefaultVhalImplTest,testGetDefaultPropertyInt)182 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyInt) {
183     VehiclePropValue value;
184     StatusCode status;
185     value.prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
186 
187     auto gotValue = mHal->get(value, &status);
188 
189     EXPECT_EQ(StatusCode::OK, status);
190     ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
191     EXPECT_EQ(2020, gotValue->value.int32Values[0]);
192 }
193 
TEST_F(DefaultVhalImplTest,testGetDefaultPropertyString)194 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyString) {
195     VehiclePropValue value;
196     StatusCode status;
197     value.prop = toInt(VehicleProperty::INFO_MAKE);
198 
199     auto gotValue = mHal->get(value, &status);
200 
201     EXPECT_EQ(StatusCode::OK, status);
202     EXPECT_EQ("Toy Vehicle", gotValue->value.stringValue);
203 }
204 
TEST_F(DefaultVhalImplTest,testGetUnknownProperty)205 TEST_F(DefaultVhalImplTest, testGetUnknownProperty) {
206     VehiclePropValue value;
207     StatusCode status;
208     value.prop = 0;
209 
210     auto gotValue = mHal->get(value, &status);
211 
212     EXPECT_EQ(StatusCode::INVALID_ARG, status);
213 }
214 
TEST_F(DefaultVhalImplTest,testSetFloat)215 TEST_F(DefaultVhalImplTest, testSetFloat) {
216     VehiclePropValue value;
217     value.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
218     value.value.floatValues.resize(1);
219     value.value.floatValues[0] = 1.0f;
220 
221     StatusCode status = mHal->set(value);
222     ASSERT_EQ(StatusCode::OK, status);
223 
224     auto gotValue = mHal->get(value, &status);
225     EXPECT_EQ(StatusCode::OK, status);
226     ASSERT_EQ((unsigned int)1, gotValue->value.floatValues.size());
227     EXPECT_EQ(1.0f, gotValue->value.floatValues[0]);
228 }
229 
TEST_F(DefaultVhalImplTest,testSetEnum)230 TEST_F(DefaultVhalImplTest, testSetEnum) {
231     VehiclePropValue value;
232     value.prop = toInt(VehicleProperty::INFO_FUEL_TYPE);
233     value.value.int32Values.resize(1);
234     value.value.int32Values[0] = (int)FuelType::FUEL_TYPE_LEADED;
235 
236     StatusCode status = mHal->set(value);
237     ASSERT_EQ(StatusCode::OK, status);
238 
239     auto gotValue = mHal->get(value, &status);
240     EXPECT_EQ(StatusCode::OK, status);
241     ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
242     EXPECT_EQ((int)FuelType::FUEL_TYPE_LEADED, gotValue->value.int32Values[0]);
243 }
244 
TEST_F(DefaultVhalImplTest,testSetInt)245 TEST_F(DefaultVhalImplTest, testSetInt) {
246     VehiclePropValue value;
247     value.prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
248     value.value.int32Values.resize(1);
249     value.value.int32Values[0] = 2021;
250 
251     StatusCode status = mHal->set(value);
252     EXPECT_EQ(StatusCode::OK, status);
253 
254     auto gotValue = mHal->get(value, &status);
255     EXPECT_EQ(StatusCode::OK, status);
256     EXPECT_EQ((unsigned int)1, gotValue->value.int32Values.size());
257     EXPECT_EQ(2021, gotValue->value.int32Values[0]);
258 }
259 
TEST_F(DefaultVhalImplTest,testSetString)260 TEST_F(DefaultVhalImplTest, testSetString) {
261     VehiclePropValue value;
262     value.prop = toInt(VehicleProperty::INFO_MAKE);
263     value.value.stringValue = "My Vehicle";
264 
265     StatusCode status = mHal->set(value);
266     ASSERT_EQ(StatusCode::OK, status);
267 
268     auto gotValue = mHal->get(value, &status);
269     EXPECT_EQ(StatusCode::OK, status);
270     EXPECT_EQ("My Vehicle", gotValue->value.stringValue);
271 }
272 
TEST_F(DefaultVhalImplTest,testSetMixed)273 TEST_F(DefaultVhalImplTest, testSetMixed) {
274     VehiclePropValue value;
275     value.prop = kMixedTypePropertyForTest;
276     // mixed prop.
277     // .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}
278     // 1 string, 1 int, 0 bool, 2 ints, 0 int64, 0 int64s, 1 float, 0 floats, 0 bytes
279     value.value.stringValue = "test";
280     value.value.int32Values.resize(3);
281     value.value.int32Values[0] = 1;
282     value.value.int32Values[1] = 2;
283     value.value.int32Values[2] = 3;
284     value.value.floatValues.resize(1);
285     value.value.floatValues[0] = 1.0f;
286 
287     StatusCode status = mHal->set(value);
288     ASSERT_EQ(StatusCode::OK, status);
289 
290     auto gotValue = mHal->get(value, &status);
291     EXPECT_EQ(StatusCode::OK, status);
292     EXPECT_EQ("test", gotValue->value.stringValue);
293     ASSERT_EQ((size_t)3, gotValue->value.int32Values.size());
294     EXPECT_EQ(1, gotValue->value.int32Values[0]);
295     EXPECT_EQ(2, gotValue->value.int32Values[1]);
296     EXPECT_EQ(3, gotValue->value.int32Values[2]);
297     ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
298     EXPECT_EQ(1.0f, gotValue->value.floatValues[0]);
299 }
300 
TEST_F(DefaultVhalImplTest,testSetUnknownProperty)301 TEST_F(DefaultVhalImplTest, testSetUnknownProperty) {
302     VehiclePropValue value;
303     value.prop = 0;
304 
305     EXPECT_EQ(StatusCode::INVALID_ARG, mHal->set(value));
306 }
307 
TEST_F(DefaultVhalImplTest,testSetStatusNotAllowed)308 TEST_F(DefaultVhalImplTest, testSetStatusNotAllowed) {
309     VehiclePropValue value;
310     value.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
311     value.status = VehiclePropertyStatus::UNAVAILABLE;
312     value.value.floatValues.resize(1);
313     value.value.floatValues[0] = 1.0f;
314 
315     StatusCode status = mHal->set(value);
316 
317     EXPECT_EQ(StatusCode::INVALID_ARG, status);
318 }
319 
TEST_F(DefaultVhalImplTest,testSubscribe)320 TEST_F(DefaultVhalImplTest, testSubscribe) {
321     // Clear existing events.
322     mEventQueue.flush();
323 
324     auto status = mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10);
325 
326     ASSERT_EQ(StatusCode::OK, status);
327 
328     std::vector<VehiclePropValuePtr> receivedEvents;
329     waitForEvents(&receivedEvents, 5);
330 
331     // Modify the speed after 5 events arrive.
332     VehiclePropValue value;
333     value.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
334     value.value.floatValues.resize(1);
335     value.value.floatValues[0] = 1.0f;
336     ASSERT_EQ(StatusCode::OK, mHal->set(value));
337 
338     waitForEvents(&receivedEvents, 10);
339 
340     // The first event should be the default value.
341     ASSERT_EQ((size_t)1, receivedEvents[0]->value.floatValues.size());
342     EXPECT_EQ(0.0f, receivedEvents[0]->value.floatValues[0]);
343     // The last event should be the value after update.
344     const auto& lastEvent = receivedEvents[receivedEvents.size() - 1];
345     ASSERT_EQ((size_t)1, lastEvent->value.floatValues.size());
346     EXPECT_EQ(1.0f, lastEvent->value.floatValues[0]);
347 }
348 
TEST_F(DefaultVhalImplTest,testSubscribeInvalidProp)349 TEST_F(DefaultVhalImplTest, testSubscribeInvalidProp) {
350     EXPECT_EQ(StatusCode::INVALID_ARG, mHal->subscribe(toInt(VehicleProperty::INFO_MAKE), 10));
351 }
352 
TEST_F(DefaultVhalImplTest,testSubscribeSampleRateOutOfRange)353 TEST_F(DefaultVhalImplTest, testSubscribeSampleRateOutOfRange) {
354     EXPECT_EQ(StatusCode::INVALID_ARG,
355               mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10.1));
356     EXPECT_EQ(StatusCode::INVALID_ARG,
357               mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0.5));
358 }
359 
TEST_F(DefaultVhalImplTest,testUnsubscribe)360 TEST_F(DefaultVhalImplTest, testUnsubscribe) {
361     auto status = mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10);
362     ASSERT_EQ(StatusCode::OK, status);
363 
364     // Wait for 0.5 seconds to generate some events.
365     std::this_thread::sleep_for(std::chrono::milliseconds(500));
366 
367     status = mHal->unsubscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED));
368     ASSERT_EQ(StatusCode::OK, status);
369 
370     // Clear all the events.
371     mEventQueue.flush();
372 
373     // Wait for 0.5 seconds.
374     std::this_thread::sleep_for(std::chrono::milliseconds(500));
375 
376     // There should be no new events generated.
377     auto events = mEventQueue.flush();
378     EXPECT_EQ((size_t)0, events.size());
379 }
380 
TEST_F(DefaultVhalImplTest,testUnsubscribeInvalidProp)381 TEST_F(DefaultVhalImplTest, testUnsubscribeInvalidProp) {
382     EXPECT_EQ(StatusCode::INVALID_ARG, mHal->unsubscribe(toInt(VehicleProperty::INFO_MAKE)));
383 }
384 
createMemfd(hidl_handle * fd)385 int createMemfd(hidl_handle* fd) {
386     native_handle_t* handle = native_handle_create(/*numFds=*/1, /*numInts=*/0);
387     int memfd = memfd_create("memfile", 0);
388     handle->data[0] = dup(memfd);
389     fd->setTo(handle, /*shouldOwn=*/true);
390     return memfd;
391 }
392 
TEST_F(DefaultVhalImplTest,testDump)393 TEST_F(DefaultVhalImplTest, testDump) {
394     hidl_vec<hidl_string> options;
395     hidl_handle fd = {};
396     int memfd = createMemfd(&fd);
397 
398     ASSERT_TRUE(mHal->dump(fd, options));
399 
400     lseek(memfd, 0, SEEK_SET);
401     char buf[10240] = {};
402     read(memfd, buf, sizeof(buf));
403     close(memfd);
404 
405     // Read one property and check that it is in the dumped info.
406     VehiclePropValue value;
407     StatusCode status;
408     value.prop = toInt(VehicleProperty::INFO_MAKE);
409     auto gotValue = mHal->get(value, &status);
410     ASSERT_EQ(StatusCode::OK, status);
411     // Server side prop store does not have timestamp.
412     gotValue->timestamp = 0;
413 
414     std::string infoMake = toString(*gotValue);
415     EXPECT_THAT(std::string(buf, sizeof(buf)), HasSubstr(infoMake));
416 }
417 
TEST_F(DefaultVhalImplTest,testSetPropInvalidAreaId)418 TEST_F(DefaultVhalImplTest, testSetPropInvalidAreaId) {
419     VehiclePropValue propNormal = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
420                                    .areaId = HVAC_ALL,
421                                    .value.int32Values = {3}};
422     StatusCode status = mHal->set(propNormal);
423 
424     EXPECT_EQ(StatusCode::OK, status);
425 
426     // HVAC_FAN_SPEED only have HVAC_ALL area config and is not allowed to set by LEFT/RIGHT.
427     VehiclePropValue propWrongId = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
428                                     .areaId = HVAC_LEFT,
429                                     .value.int32Values = {3}};
430 
431     status = mHal->set(propWrongId);
432 
433     EXPECT_EQ(StatusCode::INVALID_ARG, status);
434 }
435 
436 class DefaultVhalImplSetInvalidPropTest : public DefaultVhalImplTest,
437                                           public testing::WithParamInterface<VehiclePropValue> {};
438 
GenSetInvalidPropParams()439 std::vector<VehiclePropValue> GenSetInvalidPropParams() {
440     std::vector<VehiclePropValue> props;
441     // int prop with no value.
442     VehiclePropValue intProp = {.prop = toInt(VehicleProperty::INFO_MODEL_YEAR)};
443     props.push_back(intProp);
444 
445     // int prop with more than one value.
446     VehiclePropValue intPropWithValues = {.prop = toInt(VehicleProperty::INFO_MODEL_YEAR)};
447     intPropWithValues.value.int32Values.resize(2);
448     props.push_back(intPropWithValues);
449 
450     // int vec prop with no value.
451     VehiclePropValue intVecProp = {.prop = toInt(VehicleProperty::INFO_FUEL_TYPE)};
452     props.push_back(intVecProp);
453 
454     // int64 prop with no value.
455     VehiclePropValue int64Prop = {.prop = toInt(VehicleProperty::EPOCH_TIME)};
456     props.push_back(int64Prop);
457 
458     // int64 prop with more than one value.
459     VehiclePropValue int64PropWithValues = {.prop = toInt(VehicleProperty::EPOCH_TIME)};
460     int64PropWithValues.value.int64Values.resize(2);
461     props.push_back(int64PropWithValues);
462 
463     // int64 vec prop with no value.
464     VehiclePropValue int64VecProp = {.prop = toInt(VehicleProperty::WHEEL_TICK)};
465     props.push_back(int64VecProp);
466 
467     // float prop with no value.
468     VehiclePropValue floatProp = {.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY)};
469     props.push_back(floatProp);
470 
471     // float prop with more than one value.
472     VehiclePropValue floatPropWithValues = {.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY)};
473     floatPropWithValues.value.floatValues.resize(2);
474     props.push_back(floatPropWithValues);
475 
476     // float vec prop with no value.
477     VehiclePropValue floatVecProp = {
478             .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION)};
479     props.push_back(floatVecProp);
480 
481     // bool prop with no value.
482     VehiclePropValue boolProp = {
483             .prop = toInt(VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME)};
484     props.push_back(boolProp);
485 
486     // bool prop with more than one value.
487     VehiclePropValue boolPropWithValues = {
488             .prop = toInt(VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME)};
489     boolPropWithValues.value.int32Values.resize(2);
490     props.push_back(boolPropWithValues);
491 
492     // mixed prop.
493     // .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}
494     // 1 string, 1 int, 0 bool, 2 ints, 0 int64, 0 int64s, 1 float, 0 floats, 0 bytes
495     VehiclePropValue mixedProp1 = {.prop = kMixedTypePropertyForTest};
496     // Expect 1 bool, and 2 ints, we only have 1 value.
497     mixedProp1.value.int32Values.resize(1);
498     mixedProp1.value.floatValues.resize(1);
499     props.push_back(mixedProp1);
500 
501     VehiclePropValue mixedProp2 = {.prop = kMixedTypePropertyForTest};
502     mixedProp2.value.int32Values.resize(3);
503     // Missing float value.
504     mixedProp2.value.floatValues.resize(0);
505     props.push_back(mixedProp2);
506 
507     return props;
508 }
509 
TEST_P(DefaultVhalImplSetInvalidPropTest,testSetInvalidPropValue)510 TEST_P(DefaultVhalImplSetInvalidPropTest, testSetInvalidPropValue) {
511     VehiclePropValue value = GetParam();
512 
513     StatusCode status = mHal->set(value);
514 
515     EXPECT_EQ(StatusCode::INVALID_ARG, status);
516 }
517 
518 INSTANTIATE_TEST_SUITE_P(DefaultVhalImplSetInvalidPropTests, DefaultVhalImplSetInvalidPropTest,
519                          testing::ValuesIn(GenSetInvalidPropParams()));
520 
521 struct SetPropRangeTestCase {
522     std::string name;
523     VehiclePropValue prop;
524     StatusCode code;
525 };
526 
527 class DefaultVhalImplSetPropRangeTest : public DefaultVhalImplTest,
528                                         public testing::WithParamInterface<SetPropRangeTestCase> {};
529 
GenSetPropRangeParams()530 std::vector<SetPropRangeTestCase> GenSetPropRangeParams() {
531     std::vector<SetPropRangeTestCase> tc;
532     VehiclePropValue intPropNormal = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
533                                       .areaId = HVAC_ALL,
534                                       // min: 1, max: 7
535                                       .value.int32Values = {3}};
536     tc.push_back({"normal_case_int", intPropNormal, StatusCode::OK});
537 
538     VehiclePropValue intPropSmall = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
539                                      .areaId = HVAC_ALL,
540                                      // min: 1, max: 7
541                                      .value.int32Values = {0}};
542     tc.push_back({"normal_case_int_too_small", intPropSmall, StatusCode::INVALID_ARG});
543 
544     VehiclePropValue intPropLarge = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
545                                      .areaId = HVAC_ALL,
546                                      // min: 1, max: 7
547                                      .value.int32Values = {8}};
548     tc.push_back({"normal_case_int_too_large", intPropLarge, StatusCode::INVALID_ARG});
549 
550     VehiclePropValue floatPropNormal = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
551                                         .areaId = HVAC_LEFT,
552                                         // min: 16, max: 32
553                                         .value.floatValues = {26}};
554     tc.push_back({"normal_case_float", floatPropNormal, StatusCode::OK});
555     VehiclePropValue floatPropSmall = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
556                                        .areaId = HVAC_LEFT,
557                                        // min: 16, max: 32
558                                        .value.floatValues = {15.5}};
559     tc.push_back({"normal_case_float_too_small", floatPropSmall, StatusCode::INVALID_ARG});
560     VehiclePropValue floatPropLarge = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
561                                        .areaId = HVAC_LEFT,
562                                        // min: 16, max: 32
563                                        .value.floatValues = {32.6}};
564     tc.push_back({"normal_case_float_too_large", floatPropLarge, StatusCode::INVALID_ARG});
565 
566     return tc;
567 }
568 
TEST_P(DefaultVhalImplSetPropRangeTest,testSetPropRange)569 TEST_P(DefaultVhalImplSetPropRangeTest, testSetPropRange) {
570     SetPropRangeTestCase tc = GetParam();
571 
572     StatusCode status = mHal->set(tc.prop);
573 
574     EXPECT_EQ(tc.code, status);
575 }
576 
577 INSTANTIATE_TEST_SUITE_P(
578         DefaultVhalImplSetPropRangeTests, DefaultVhalImplSetPropRangeTest,
579         testing::ValuesIn(GenSetPropRangeParams()),
__anon983c06f70202(const testing::TestParamInfo<DefaultVhalImplSetPropRangeTest::ParamType>& info) 580         [](const testing::TestParamInfo<DefaultVhalImplSetPropRangeTest::ParamType>& info) {
581             return info.param.name;
582         });
583 
getPropIdString(VehicleProperty prop)584 std::string getPropIdString(VehicleProperty prop) {
585     char s[MAX_PROP_ID_LENGTH] = {};
586     snprintf(s, sizeof(s), "%d", toInt(prop));
587     return std::string(s);
588 }
589 
590 struct OptionsTestCase {
591     std::string name;
592     hidl_vec<hidl_string> options;
593     std::string expectMsg;
594 };
595 
596 class DefaultVhalImplOptionsTest : public DefaultVhalImplTest,
597                                    public testing::WithParamInterface<OptionsTestCase> {};
598 
TEST_P(DefaultVhalImplOptionsTest,testInvalidOptions)599 TEST_P(DefaultVhalImplOptionsTest, testInvalidOptions) {
600     auto tc = GetParam();
601     hidl_handle fd = {};
602     int memfd = createMemfd(&fd);
603 
604     bool shouldDump = mHal->dump(fd, tc.options);
605 
606     EXPECT_FALSE(shouldDump);
607     char buf[10240] = {};
608     lseek(memfd, 0, SEEK_SET);
609     read(memfd, buf, sizeof(buf));
610     EXPECT_THAT(std::string(buf), HasSubstr(tc.expectMsg));
611 }
612 
GenInvalidOptions()613 std::vector<OptionsTestCase> GenInvalidOptions() {
614     return {{"no_command", {"--debughal"}, "No command specified"},
615             {"unknown_command", {"--debughal", "--unknown"}, "Unknown command: \"--unknown\""},
616             {"help", {"--debughal", "--help"}, "Help:"},
617             {"genfakedata_no_subcommand",
618              {"--debughal", "--genfakedata"},
619              "No subcommand specified for genfakedata"},
620             {"genfakedata_unknown_subcommand",
621              {"--debughal", "--genfakedata", "--unknown"},
622              "Unknown command: \"--unknown\""},
623             {"genfakedata_start_linear_no_args",
624              {"--debughal", "--genfakedata", "--startlinear"},
625              "incorrect argument count"},
626             {"genfakedata_start_linear_invalid_propId",
627              {"--debughal", "--genfakedata", "--startlinear", "abcd", "0.1", "0.1", "0.1", "0.1",
628               "100000000"},
629              "failed to parse propdID as int: \"abcd\""},
630             {"genfakedata_start_linear_invalid_middleValue",
631              {"--debughal", "--genfakedata", "--startlinear", "1", "abcd", "0.1", "0.1", "0.1",
632               "100000000"},
633              "failed to parse middleValue as float: \"abcd\""},
634             {"genfakedata_start_linear_invalid_currentValue",
635              {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "abcd", "0.1", "0.1",
636               "100000000"},
637              "failed to parse currentValue as float: \"abcd\""},
638             {"genfakedata_start_linear_invalid_dispersion",
639              {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "abcd", "0.1",
640               "100000000"},
641              "failed to parse dispersion as float: \"abcd\""},
642             {"genfakedata_start_linear_invalid_increment",
643              {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "abcd",
644               "100000000"},
645              "failed to parse increment as float: \"abcd\""},
646             {"genfakedata_start_linear_invalid_interval",
647              {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "0.1",
648               "0.1"},
649              "failed to parse interval as int: \"0.1\""},
650             {"genfakedata_stop_linear_no_args",
651              {"--debughal", "--genfakedata", "--stoplinear"},
652              "incorrect argument count"},
653             {"genfakedata_stop_linear_invalid_propId",
654              {"--debughal", "--genfakedata", "--stoplinear", "abcd"},
655              "failed to parse propdID as int: \"abcd\""},
656             {"genfakedata_startjson_no_args",
657              {"--debughal", "--genfakedata", "--startjson"},
658              "incorrect argument count"},
659             {"genfakedata_startjson_invalid_repetition",
660              {"--debughal", "--genfakedata", "--startjson", "file", "0.1"},
661              "failed to parse repetition as int: \"0.1\""},
662             {"genfakedata_startjson_invalid_json_file",
663              {"--debughal", "--genfakedata", "--startjson", "file", "1"},
664              "invalid JSON file"},
665             {"genfakedata_stopjson_no_args",
666              {"--debughal", "--genfakedata", "--stopjson"},
667              "incorrect argument count"},
668             {"genfakedata_keypress_no_args",
669              {"--debughal", "--genfakedata", "--keypress"},
670              "incorrect argument count"},
671             {"genfakedata_keypress_invalid_keyCode",
672              {"--debughal", "--genfakedata", "--keypress", "0.1", "1"},
673              "failed to parse keyCode as int: \"0.1\""},
674             {"genfakedata_keypress_invalid_display",
675              {"--debughal", "--genfakedata", "--keypress", "1", "0.1"},
676              "failed to parse display as int: \"0.1\""},
677             {"setint_no_args", {"--debughal", "--setint"}, "incorrect argument count"},
678             {"setint_invalid_prop_id",
679              {"--debughal", "--setint", "abcd", "0", "0", "0"},
680              "failed to parse propID as int: \"abcd\""},
681             {"setint_invalid_value",
682              {"--debughal", "--setint", "0", "1.1", "0", "0"},
683              "failed to parse value as int: \"1.1\""},
684             {"setint_invalid_timestamp",
685              {"--debughal", "--setint", "0", "0", "1.1", "0"},
686              "failed to parse timestamp as int: \"1.1\""},
687             {"setint_invalid_areaId",
688              {"--debughal", "--setint", "0", "0", "0", "1.1"},
689              "failed to parse areaID as int: \"1.1\""},
690             {"setbool_no_args", {"--debughal", "--setbool"}, "incorrect argument count"},
691             {"setbool_invalid_value",
692              {"--debughal", "--setbool", "0", "1", "0", "0"},
693              "failed to parse value as bool"},
694             {"setfloat_no_args", {"--debughal", "--setfloat"}, "incorrect argument count"},
695             {"setfloat_invalid_value",
696              {"--debughal", "--setfloat", "0", "abcd", "0", "0"},
697              "failed to parse value as float: \"abcd\""}};
698 }
699 
700 INSTANTIATE_TEST_SUITE_P(
701         DefaultVhalImplOptionsTests, DefaultVhalImplOptionsTest,
702         testing::ValuesIn(GenInvalidOptions()),
__anon983c06f70302(const testing::TestParamInfo<DefaultVhalImplOptionsTest::ParamType>& info) 703         [](const testing::TestParamInfo<DefaultVhalImplOptionsTest::ParamType>& info) {
704             return info.param.name;
705         });
706 
TEST_F(DefaultVhalImplTest,testDebugGenFakeDataLinear)707 TEST_F(DefaultVhalImplTest, testDebugGenFakeDataLinear) {
708     // Start a fake linear data generator for vehicle speed at 0.1s interval.
709     // range: 0 - 100, current value: 30, step: 20.
710     hidl_vec<hidl_string> options = {"--debughal",
711                                      "--genfakedata",
712                                      "--startlinear",
713                                      getPropIdString(VehicleProperty::PERF_VEHICLE_SPEED),
714                                      /*middleValue=*/"50",
715                                      /*currentValue=*/"30",
716                                      /*dispersion=*/"50",
717                                      /*increment=*/"20",
718                                      /*interval=*/"100000000"};
719     hidl_handle fd = {};
720     int memfd = createMemfd(&fd);
721     // Clear existing events.
722     mEventQueue.flush();
723 
724     EXPECT_FALSE(mHal->dump(fd, options));
725 
726     lseek(memfd, 0, SEEK_SET);
727     char buf[10240] = {};
728     // The dumped info should be empty.
729     read(memfd, buf, sizeof(buf));
730     EXPECT_STREQ("", buf);
731 
732     std::this_thread::sleep_for(std::chrono::milliseconds(1000));
733 
734     auto events = mEventQueue.flush();
735     // We should get 10 events ideally, but let's be safe here.
736     ASSERT_LE((size_t)5, events.size());
737     int32_t value = 30;
738     for (size_t i = 0; i < 5; i++) {
739         ASSERT_EQ((size_t)1, events[i]->value.floatValues.size());
740         EXPECT_EQ((float)value, events[i]->value.floatValues[0]);
741         value = (value + 20) % 100;
742     }
743 
744     // Stop the linear generator.
745     options = {"--debughal", "--genfakedata", "--stoplinear",
746                getPropIdString(VehicleProperty::PERF_VEHICLE_SPEED)};
747     EXPECT_FALSE(mHal->dump(fd, options));
748 
749     // The dumped info should be empty.
750     lseek(memfd, 0, SEEK_SET);
751     read(memfd, buf, sizeof(buf));
752     EXPECT_STREQ("", buf);
753 
754     close(memfd);
755 
756     // Clear existing events.
757     mEventQueue.flush();
758     std::this_thread::sleep_for(std::chrono::milliseconds(500));
759     // Technically there should be no new events generated, however, there might still be one event
760     // in the queue while we are stopping the generator.
761     EXPECT_LE(mEventQueue.flush().size(), 1u);
762 }
763 
getTestFilePath(const char * filename)764 std::string getTestFilePath(const char* filename) {
765     static std::string baseDir = android::base::GetExecutableDirectory();
766     return baseDir + "/" + filename;
767 }
768 
TEST_F(DefaultVhalImplTest,testDebugGenFakeDataJson)769 TEST_F(DefaultVhalImplTest, testDebugGenFakeDataJson) {
770     hidl_vec<hidl_string> options = {"--debughal", "--genfakedata", "--startjson",
771                                      getTestFilePath("prop.json"), "2"};
772     hidl_handle fd = {};
773     int memfd = createMemfd(&fd);
774     // Clear existing events.
775     mEventQueue.flush();
776 
777     EXPECT_FALSE(mHal->dump(fd, options));
778 
779     lseek(memfd, 0, SEEK_SET);
780     char buf[10240] = {};
781     // The dumped info should be empty.
782     read(memfd, buf, sizeof(buf));
783     EXPECT_STREQ("", buf);
784 
785     // wait for some time.
786     std::this_thread::sleep_for(std::chrono::milliseconds(100));
787 
788     auto events = mEventQueue.flush();
789     ASSERT_EQ((size_t)8, events.size());
790     // First set of events, we test 1st and the last.
791     EXPECT_EQ((size_t)1, events[0]->value.int32Values.size());
792     EXPECT_EQ(8, events[0]->value.int32Values[0]);
793     EXPECT_EQ((size_t)1, events[3]->value.int32Values.size());
794     EXPECT_EQ(10, events[3]->value.int32Values[0]);
795     // Second set of the same events.
796     EXPECT_EQ((size_t)1, events[4]->value.int32Values.size());
797     EXPECT_EQ(8, events[4]->value.int32Values[0]);
798     EXPECT_EQ((size_t)1, events[7]->value.int32Values.size());
799     EXPECT_EQ(10, events[7]->value.int32Values[0]);
800 }
801 
TEST_F(DefaultVhalImplTest,testDebugGenFakeDataKeyPress)802 TEST_F(DefaultVhalImplTest, testDebugGenFakeDataKeyPress) {
803     hidl_vec<hidl_string> options = {"--debughal", "--genfakedata", "--keypress", "1", "2"};
804     hidl_handle fd = {};
805     int memfd = createMemfd(&fd);
806     // Clear existing events.
807     mEventQueue.flush();
808 
809     EXPECT_FALSE(mHal->dump(fd, options));
810 
811     lseek(memfd, 0, SEEK_SET);
812     char buf[10240] = {};
813     // The dumped info should be empty.
814     read(memfd, buf, sizeof(buf));
815     EXPECT_STREQ("", buf);
816 
817     auto events = mEventQueue.flush();
818     ASSERT_EQ((size_t)2, events.size());
819     EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[0]->prop);
820     EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[1]->prop);
821     ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
822     ASSERT_EQ((size_t)3, events[1]->value.int32Values.size());
823     EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_DOWN), events[0]->value.int32Values[0]);
824     EXPECT_EQ(1, events[0]->value.int32Values[1]);
825     EXPECT_EQ(2, events[0]->value.int32Values[2]);
826     EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_UP), events[1]->value.int32Values[0]);
827     EXPECT_EQ(1, events[1]->value.int32Values[1]);
828     EXPECT_EQ(2, events[1]->value.int32Values[2]);
829 }
830 
TEST_F(DefaultVhalImplTest,testHeartBeatEvent)831 TEST_F(DefaultVhalImplTest, testHeartBeatEvent) {
832     // A heart beat would be sent every 3s, but let's wait for 6s to be sure at least 2 events have
833     // been generated (at 0s and 3s).
834     std::this_thread::sleep_for(std::chrono::milliseconds(6000));
835 
836     auto events = mHeartBeatQueue.flush();
837     ASSERT_GE(events.size(), (size_t)2);
838     ASSERT_EQ(toInt(VehicleProperty::VHAL_HEARTBEAT), events[0]->prop);
839 }
840 
TEST_F(DefaultVhalImplTest,testVendorOverrideProperties)841 TEST_F(DefaultVhalImplTest, testVendorOverrideProperties) {
842     // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
843     mHal.reset();
844     // Create a new Default VHAL and reinitialize it to load the override properties.
845     std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
846     mPropStore.reset(new VehiclePropertyStore);
847     mConnector.reset(new DefaultVehicleConnector);
848     mConnector->setValuePool(&mValueObjectPool);
849     mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
850     // Set vendor override directory.
851     DefaultVhalImplTestHelper helper(mConnector.get());
852     helper.overrideProperties(overrideDir.c_str());
853 
854     initHal();
855 
856     VehiclePropValue value;
857     StatusCode status;
858     // This is the same as the prop in 'gear_selection.json'.
859     value.prop = toInt(VehicleProperty::GEAR_SELECTION);
860 
861     auto gotValue = mHal->get(value, &status);
862 
863     ASSERT_EQ(StatusCode::OK, status);
864     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
865     ASSERT_EQ(8, gotValue->value.int32Values[0]);
866 
867     // If we set the value, it should update despite the override.
868     value.prop = toInt(VehicleProperty::GEAR_SELECTION);
869     value.value.int32Values.resize(1);
870     value.value.int32Values[0] = 5;
871 
872     status = mHal->set(value);
873     ASSERT_EQ(StatusCode::OK, status);
874 
875     gotValue = mHal->get(value, &status);
876     ASSERT_EQ(StatusCode::OK, status);
877     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
878     ASSERT_EQ(5, gotValue->value.int32Values[0]);
879 }
880 
TEST_F(DefaultVhalImplTest,testVendorOverridePropertiesMultipleAreas)881 TEST_F(DefaultVhalImplTest, testVendorOverridePropertiesMultipleAreas) {
882     // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
883     mHal.reset();
884     // Create a new Default VHAL and reinitialize it to load the override properties.
885     std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
886     mPropStore.reset(new VehiclePropertyStore);
887     mConnector.reset(new DefaultVehicleConnector);
888     mConnector->setValuePool(&mValueObjectPool);
889     mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
890     // Set vendor override directory.
891     DefaultVhalImplTestHelper helper(mConnector.get());
892     helper.overrideProperties(overrideDir.c_str());
893 
894     initHal();
895 
896     VehiclePropValue value;
897     StatusCode status;
898     // This is the same as the prop in 'hvac_temperature_set.json'.
899     value.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
900     value.areaId = HVAC_LEFT;
901 
902     auto gotValue = mHal->get(value, &status);
903 
904     ASSERT_EQ(StatusCode::OK, status);
905     ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
906     ASSERT_EQ(30.0f, gotValue->value.floatValues[0]);
907 
908     // HVAC_RIGHT should not be affected and return the default value.
909     value.areaId = HVAC_RIGHT;
910 
911     gotValue = mHal->get(value, &status);
912 
913     ASSERT_EQ(StatusCode::OK, status);
914     ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
915     ASSERT_EQ(20.0f, gotValue->value.floatValues[0]);
916 }
917 
TEST_F(DefaultVhalImplTest,testVendorOverridePropertiesDirDoesNotExist)918 TEST_F(DefaultVhalImplTest, testVendorOverridePropertiesDirDoesNotExist) {
919     // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
920     mHal.reset();
921     // Create a new Default VHAL and reinitialize it to load the override properties.
922     mPropStore.reset(new VehiclePropertyStore);
923     mConnector.reset(new DefaultVehicleConnector);
924     mConnector->setValuePool(&mValueObjectPool);
925     mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
926     // Set vendor override directory to a non-existing dir
927     DefaultVhalImplTestHelper helper(mConnector.get());
928     helper.overrideProperties("123");
929     initHal();
930 
931     VehiclePropValue value;
932     StatusCode status;
933     value.prop = toInt(VehicleProperty::GEAR_SELECTION);
934 
935     auto gotValue = mHal->get(value, &status);
936 
937     // We should get the default value.
938     ASSERT_EQ(StatusCode::OK, status);
939     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
940     ASSERT_EQ(4, gotValue->value.int32Values[0]);
941 }
942 
TEST_F(DefaultVhalImplTest,testGetObd2FreezeFrameNoTimestamp)943 TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameNoTimestamp) {
944     VehiclePropValue value;
945     value.prop = OBD2_FREEZE_FRAME;
946     StatusCode status;
947 
948     auto gotValue = mHal->get(value, &status);
949 
950     ASSERT_EQ(StatusCode::INVALID_ARG, status);
951 }
952 
TEST_F(DefaultVhalImplTest,testGetObd2FreezeFrameInvalidTimestamp)953 TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameInvalidTimestamp) {
954     VehiclePropValue value;
955     value.prop = OBD2_FREEZE_FRAME;
956     value.value.int64Values.resize(1);
957     value.value.int64Values[0] = 0;
958     StatusCode status;
959 
960     auto gotValue = mHal->get(value, &status);
961 
962     ASSERT_EQ(StatusCode::INVALID_ARG, status);
963 }
964 
TEST_F(DefaultVhalImplTest,testGetObd2FreezeFrameInfoGetObd2FreezeFrame)965 TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameInfoGetObd2FreezeFrame) {
966     VehiclePropValue value;
967     value.prop = OBD2_FREEZE_FRAME_INFO;
968     StatusCode status;
969 
970     auto gotValue = mHal->get(value, &status);
971 
972     ASSERT_EQ(StatusCode::OK, status);
973     ASSERT_EQ((size_t)3, gotValue->value.int64Values.size());
974 
975     std::vector<std::string> dtcs;
976     std::vector<std::string> sampleDtcs = {"P0070", "P0102", "P0123"};
977     for (int64_t timestamp : gotValue->value.int64Values) {
978         VehiclePropValue freezeFrameRequest;
979         freezeFrameRequest.prop = OBD2_FREEZE_FRAME;
980         freezeFrameRequest.value.int64Values.resize(1);
981         freezeFrameRequest.value.int64Values[0] = timestamp;
982 
983         auto freezeFrameValue = mHal->get(freezeFrameRequest, &status);
984 
985         ASSERT_EQ(StatusCode::OK, status);
986         // Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 1
987         EXPECT_EQ((size_t)32, freezeFrameValue->value.int32Values.size());
988         // Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 1
989         EXPECT_EQ((size_t)71, freezeFrameValue->value.floatValues.size());
990         // (intValues.size() + floatValues.size()) / 8
991         EXPECT_EQ((size_t)13, freezeFrameValue->value.bytes.size());
992 
993         dtcs.push_back(freezeFrameValue->value.stringValue);
994     }
995 
996     for (std::string expectDtc : sampleDtcs) {
997         EXPECT_NE(std::find(dtcs.begin(), dtcs.end(), expectDtc), dtcs.end());
998     }
999 }
1000 
TEST_F(DefaultVhalImplTest,testGetObd2LiveFrame)1001 TEST_F(DefaultVhalImplTest, testGetObd2LiveFrame) {
1002     VehiclePropValue value;
1003     value.prop = OBD2_LIVE_FRAME;
1004     StatusCode status;
1005 
1006     auto gotValue = mHal->get(value, &status);
1007 
1008     ASSERT_EQ(StatusCode::OK, status);
1009     // Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 1
1010     EXPECT_EQ((size_t)32, gotValue->value.int32Values.size());
1011     // Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 1
1012     EXPECT_EQ((size_t)71, gotValue->value.floatValues.size());
1013     // (intValues.size() + floatValues.size()) / 8
1014     EXPECT_EQ((size_t)13, gotValue->value.bytes.size());
1015 }
1016 
TEST_F(DefaultVhalImplTest,testClearObd2FreezeFrameAll)1017 TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameAll) {
1018     VehiclePropValue value;
1019     value.prop = OBD2_FREEZE_FRAME_CLEAR;
1020     // No int64Values is to clear all frames.
1021 
1022     auto status = mHal->set(value);
1023 
1024     EXPECT_EQ(StatusCode::OK, status);
1025 
1026     VehiclePropValue freezeFrameRequest;
1027     freezeFrameRequest.prop = OBD2_FREEZE_FRAME;
1028     freezeFrameRequest.value.int64Values.resize(1);
1029 
1030     auto gotValue = mHal->get(freezeFrameRequest, &status);
1031 
1032     EXPECT_EQ(StatusCode::NOT_AVAILABLE, status);
1033 
1034     VehiclePropValue freezeFrameInfoRequest;
1035     freezeFrameInfoRequest.prop = OBD2_FREEZE_FRAME_INFO;
1036 
1037     gotValue = mHal->get(freezeFrameInfoRequest, &status);
1038 
1039     EXPECT_EQ(StatusCode::OK, status);
1040     EXPECT_EQ((size_t)0, gotValue->value.int64Values.size());
1041 }
1042 
TEST_F(DefaultVhalImplTest,testClearObd2FreezeFrameOneFrame)1043 TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameOneFrame) {
1044     // Get existing freeze frame info first.
1045     VehiclePropValue frameInfoRequest;
1046     frameInfoRequest.prop = OBD2_FREEZE_FRAME_INFO;
1047     StatusCode status;
1048     auto gotValue = mHal->get(frameInfoRequest, &status);
1049     ASSERT_EQ(StatusCode::OK, status);
1050     ASSERT_EQ((size_t)3, gotValue->value.int64Values.size());
1051 
1052     VehiclePropValue clearRequest;
1053     int64_t timestamp = gotValue->value.int64Values[0];
1054     clearRequest.prop = OBD2_FREEZE_FRAME_CLEAR;
1055     clearRequest.value.int64Values.resize(1);
1056     clearRequest.value.int64Values[0] = timestamp;
1057 
1058     // Try to clear the first frame.
1059     status = mHal->set(clearRequest);
1060 
1061     // Get freeze frame info again.
1062     gotValue = mHal->get(frameInfoRequest, &status);
1063 
1064     ASSERT_EQ(StatusCode::OK, status);
1065     // Now we should only have 2 frames.
1066     ASSERT_EQ((size_t)2, gotValue->value.int64Values.size());
1067 
1068     // Try to get the deleted frame, should fail.
1069     VehiclePropValue frameRequest;
1070     frameRequest.prop = OBD2_FREEZE_FRAME;
1071     frameRequest.value.int64Values.resize(1);
1072     frameRequest.value.int64Values[0] = timestamp;
1073 
1074     gotValue = mHal->get(frameRequest, &status);
1075 
1076     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1077 
1078     // Clear the same frame again should fail.
1079     status = mHal->set(clearRequest);
1080 
1081     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1082 }
1083 
TEST_F(DefaultVhalImplTest,testGetUserPropertySetOnly)1084 TEST_F(DefaultVhalImplTest, testGetUserPropertySetOnly) {
1085     VehiclePropValue value;
1086     value.prop = toInt(VehicleProperty::INITIAL_USER_INFO);
1087     StatusCode status;
1088 
1089     mHal->get(value, &status);
1090 
1091     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1092 
1093     value.prop = toInt(VehicleProperty::SWITCH_USER);
1094 
1095     mHal->get(value, &status);
1096 
1097     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1098 
1099     value.prop = toInt(VehicleProperty::CREATE_USER);
1100 
1101     mHal->get(value, &status);
1102 
1103     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1104 
1105     value.prop = toInt(VehicleProperty::REMOVE_USER);
1106 
1107     mHal->get(value, &status);
1108 
1109     ASSERT_EQ(StatusCode::INVALID_ARG, status);
1110 }
1111 
TEST_F(DefaultVhalImplTest,testGetUserIdAssoc)1112 TEST_F(DefaultVhalImplTest, testGetUserIdAssoc) {
1113     VehiclePropValue value;
1114     value.prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
1115     StatusCode status;
1116 
1117     mHal->get(value, &status);
1118 
1119     // Default returns NOT_AVAILABLE.
1120     ASSERT_EQ(StatusCode::NOT_AVAILABLE, status);
1121 
1122     // This is the same example as used in User HAL Emulation doc.
1123     VehiclePropValue setValue = {
1124             .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
1125             .areaId = 1,
1126             .value.int32Values = {666, 1, 1, 2},
1127     };
1128 
1129     status = mHal->set(setValue);
1130 
1131     ASSERT_EQ(StatusCode::OK, status);
1132 
1133     auto gotValue = mHal->get(value, &status);
1134 
1135     ASSERT_EQ(StatusCode::OK, status);
1136     ASSERT_EQ((size_t)4, gotValue->value.int32Values.size());
1137     EXPECT_EQ(1, gotValue->areaId);
1138     EXPECT_EQ(666, gotValue->value.int32Values[0]);
1139     EXPECT_EQ(1, gotValue->value.int32Values[1]);
1140     EXPECT_EQ(1, gotValue->value.int32Values[2]);
1141     EXPECT_EQ(2, gotValue->value.int32Values[3]);
1142     EXPECT_EQ(toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), gotValue->prop);
1143 }
1144 
TEST_F(DefaultVhalImplTest,testSwitchUser)1145 TEST_F(DefaultVhalImplTest, testSwitchUser) {
1146     // This is the same example as used in User HAL Emulation doc.
1147     VehiclePropValue setValue = {
1148             .prop = toInt(VehicleProperty::SWITCH_USER),
1149             .areaId = 1,
1150             .value.int32Values = {666, 3, 2},
1151     };
1152 
1153     auto status = mHal->set(setValue);
1154 
1155     ASSERT_EQ(StatusCode::OK, status);
1156 
1157     // Simulate a request from Android side.
1158     setValue = {
1159             .prop = toInt(VehicleProperty::SWITCH_USER),
1160             .areaId = 0,
1161             .value.int32Values = {666, 3},
1162     };
1163     // Clear existing events.
1164     mEventQueue.flush();
1165 
1166     status = mHal->set(setValue);
1167 
1168     ASSERT_EQ(StatusCode::OK, status);
1169 
1170     // Should generate an event for user hal response.
1171     auto events = mEventQueue.flush();
1172     ASSERT_EQ((size_t)1, events.size());
1173     EXPECT_EQ(1, events[0]->areaId);
1174     EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop);
1175     ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
1176     EXPECT_EQ(666, events[0]->value.int32Values[0]);
1177     EXPECT_EQ(3, events[0]->value.int32Values[1]);
1178     EXPECT_EQ(2, events[0]->value.int32Values[2]);
1179 
1180     // Try to get switch_user again, should return default value.
1181     status = mHal->set(setValue);
1182     ASSERT_EQ(StatusCode::OK, status);
1183 
1184     events = mEventQueue.flush();
1185     ASSERT_EQ((size_t)1, events.size());
1186     EXPECT_EQ(0, events[0]->areaId);
1187     EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop);
1188     ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
1189     // Request ID
1190     EXPECT_EQ(666, events[0]->value.int32Values[0]);
1191     // VEHICLE_RESPONSE
1192     EXPECT_EQ(3, events[0]->value.int32Values[1]);
1193     // SUCCESS
1194     EXPECT_EQ(1, events[0]->value.int32Values[2]);
1195 }
1196 
TEST_F(DefaultVhalImplTest,testCreateUser)1197 TEST_F(DefaultVhalImplTest, testCreateUser) {
1198     // This is the same example as used in User HAL Emulation doc.
1199     VehiclePropValue setValue = {
1200             .prop = toInt(VehicleProperty::CREATE_USER),
1201             .areaId = 1,
1202             .value.int32Values = {666, 2},
1203     };
1204 
1205     auto status = mHal->set(setValue);
1206 
1207     ASSERT_EQ(StatusCode::OK, status);
1208 
1209     // Simulate a request from Android side.
1210     setValue = {
1211             .prop = toInt(VehicleProperty::CREATE_USER),
1212             .areaId = 0,
1213             .value.int32Values = {666},
1214     };
1215     // Clear existing events.
1216     mEventQueue.flush();
1217 
1218     status = mHal->set(setValue);
1219 
1220     ASSERT_EQ(StatusCode::OK, status);
1221 
1222     // Should generate an event for user hal response.
1223     auto events = mEventQueue.flush();
1224     ASSERT_EQ((size_t)1, events.size());
1225     EXPECT_EQ(1, events[0]->areaId);
1226     EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop);
1227     ASSERT_EQ((size_t)2, events[0]->value.int32Values.size());
1228     EXPECT_EQ(666, events[0]->value.int32Values[0]);
1229     EXPECT_EQ(2, events[0]->value.int32Values[1]);
1230 
1231     // Try to get create_user again, should return default value.
1232     status = mHal->set(setValue);
1233     ASSERT_EQ(StatusCode::OK, status);
1234 
1235     events = mEventQueue.flush();
1236     ASSERT_EQ((size_t)1, events.size());
1237     EXPECT_EQ(0, events[0]->areaId);
1238     EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop);
1239     ASSERT_EQ((size_t)2, events[0]->value.int32Values.size());
1240     // Request ID
1241     EXPECT_EQ(666, events[0]->value.int32Values[0]);
1242     // SUCCESS
1243     EXPECT_EQ(1, events[0]->value.int32Values[1]);
1244 }
1245 
TEST_F(DefaultVhalImplTest,testInitialUserInfo)1246 TEST_F(DefaultVhalImplTest, testInitialUserInfo) {
1247     // This is the same example as used in User HAL Emulation doc.
1248     VehiclePropValue setValue = {
1249             .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
1250             .areaId = 1,
1251             .value.int32Values = {666, 1, 11},
1252     };
1253 
1254     auto status = mHal->set(setValue);
1255 
1256     ASSERT_EQ(StatusCode::OK, status);
1257 
1258     // Simulate a request from Android side.
1259     setValue = {
1260             .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
1261             .areaId = 0,
1262             .value.int32Values = {3},
1263     };
1264     // Clear existing events.
1265     mEventQueue.flush();
1266 
1267     status = mHal->set(setValue);
1268 
1269     ASSERT_EQ(StatusCode::OK, status);
1270 
1271     // Should generate an event for user hal response.
1272     auto events = mEventQueue.flush();
1273     ASSERT_EQ((size_t)1, events.size());
1274     EXPECT_EQ(1, events[0]->areaId);
1275     EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop);
1276     ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
1277     EXPECT_EQ(3, events[0]->value.int32Values[0]);
1278     EXPECT_EQ(1, events[0]->value.int32Values[1]);
1279     EXPECT_EQ(11, events[0]->value.int32Values[2]);
1280 
1281     // Try to get create_user again, should return default value.
1282     status = mHal->set(setValue);
1283     ASSERT_EQ(StatusCode::OK, status);
1284 
1285     events = mEventQueue.flush();
1286     ASSERT_EQ((size_t)1, events.size());
1287     EXPECT_EQ(0, events[0]->areaId);
1288     EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop);
1289     ASSERT_EQ((size_t)4, events[0]->value.int32Values.size());
1290     // Request ID
1291     EXPECT_EQ(3, events[0]->value.int32Values[0]);
1292     // ACTION: DEFAULT
1293     EXPECT_EQ(0, events[0]->value.int32Values[1]);
1294     // User id: 0
1295     EXPECT_EQ(0, events[0]->value.int32Values[2]);
1296     // Flags: 0
1297     EXPECT_EQ(0, events[0]->value.int32Values[3]);
1298 }
1299 
TEST_F(DefaultVhalImplTest,testDebugSetInt)1300 TEST_F(DefaultVhalImplTest, testDebugSetInt) {
1301     hidl_vec<hidl_string> options = {"--debughal", "--setint",
1302                                      getPropIdString(VehicleProperty::INFO_MODEL_YEAR), "2022",
1303                                      "1000"};
1304     hidl_handle fd = {};
1305     int memfd = createMemfd(&fd);
1306     // Clear existing events.
1307     mEventQueue.flush();
1308 
1309     EXPECT_FALSE(mHal->dump(fd, options));
1310 
1311     lseek(memfd, 0, SEEK_SET);
1312     char buf[10240] = {};
1313     // The dumped info should be empty.
1314     read(memfd, buf, sizeof(buf));
1315     EXPECT_STREQ("", buf);
1316 
1317     auto events = mEventQueue.flush();
1318     ASSERT_EQ((size_t)1, events.size());
1319     ASSERT_EQ((size_t)1, events[0]->value.int32Values.size());
1320     EXPECT_EQ(2022, events[0]->value.int32Values[0]);
1321     EXPECT_EQ(1000, events[0]->timestamp);
1322 
1323     VehiclePropValue value;
1324     StatusCode status;
1325     value.prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
1326     auto gotValue = mHal->get(value, &status);
1327     ASSERT_EQ(StatusCode::OK, status);
1328     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
1329     EXPECT_EQ(2022, gotValue->value.int32Values[0]);
1330 }
1331 
TEST_F(DefaultVhalImplTest,testDebugSetBool)1332 TEST_F(DefaultVhalImplTest, testDebugSetBool) {
1333     char doorLeft[100];
1334     snprintf(doorLeft, sizeof(doorLeft), "%d", DOOR_1_LEFT);
1335     hidl_vec<hidl_string> options = {
1336             "--debughal", "--setbool", getPropIdString(VehicleProperty::DOOR_LOCK),
1337             "false",      "1000",      doorLeft};
1338     hidl_handle fd = {};
1339     int memfd = createMemfd(&fd);
1340     // Clear existing events.
1341     mEventQueue.flush();
1342 
1343     EXPECT_FALSE(mHal->dump(fd, options));
1344 
1345     lseek(memfd, 0, SEEK_SET);
1346     char buf[10240] = {};
1347     // The dumped info should be empty.
1348     read(memfd, buf, sizeof(buf));
1349     EXPECT_STREQ("", buf);
1350 
1351     auto events = mEventQueue.flush();
1352     ASSERT_EQ((size_t)1, events.size());
1353     EXPECT_EQ(0, events[0]->value.int32Values[0]);
1354     EXPECT_EQ(DOOR_1_LEFT, events[0]->areaId);
1355     EXPECT_EQ(1000, events[0]->timestamp);
1356 
1357     VehiclePropValue value;
1358     StatusCode status;
1359     value.prop = toInt(VehicleProperty::DOOR_LOCK);
1360     value.areaId = DOOR_1_LEFT;
1361     auto gotValue = mHal->get(value, &status);
1362     ASSERT_EQ(StatusCode::OK, status);
1363     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
1364     EXPECT_EQ(0, gotValue->value.int32Values[0]);
1365 
1366     value.areaId = DOOR_1_RIGHT;
1367     gotValue = mHal->get(value, &status);
1368     ASSERT_EQ(StatusCode::OK, status);
1369     ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
1370     EXPECT_EQ(1, gotValue->value.int32Values[0]);
1371 }
1372 
TEST_F(DefaultVhalImplTest,testDebugSetFloat)1373 TEST_F(DefaultVhalImplTest, testDebugSetFloat) {
1374     hidl_vec<hidl_string> options = {"--debughal", "--setfloat",
1375                                      getPropIdString(VehicleProperty::INFO_FUEL_CAPACITY), "10.5",
1376                                      "1000"};
1377     hidl_handle fd = {};
1378     int memfd = createMemfd(&fd);
1379     // Clear existing events.
1380     mEventQueue.flush();
1381 
1382     EXPECT_FALSE(mHal->dump(fd, options));
1383 
1384     lseek(memfd, 0, SEEK_SET);
1385     char buf[10240] = {};
1386     // The dumped info should be empty.
1387     read(memfd, buf, sizeof(buf));
1388     EXPECT_STREQ("", buf);
1389 
1390     auto events = mEventQueue.flush();
1391     ASSERT_EQ((size_t)1, events.size());
1392     ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
1393     EXPECT_EQ(10.5, events[0]->value.floatValues[0]);
1394     EXPECT_EQ(1000, events[0]->timestamp);
1395 
1396     VehiclePropValue value;
1397     StatusCode status;
1398     value.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
1399     auto gotValue = mHal->get(value, &status);
1400     ASSERT_EQ(StatusCode::OK, status);
1401     ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
1402     EXPECT_EQ(10.5, gotValue->value.floatValues[0]);
1403 }
1404 
1405 }  // namespace
1406