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