1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "HidlHalPropValue.h"
18 #include "HidlVhalClient.h"
19
20 #include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
21 #include <android-base/result.h>
22 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <utils/StrongPointer.h>
26
27 #include <VehicleUtils.h>
28
29 #include <vector>
30
31 namespace android {
32 namespace frameworks {
33 namespace automotive {
34 namespace vhal {
35 namespace hidl_test {
36
37 using ::aidl::android::hardware::automotive::vehicle::PropIdAreaId;
38 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
39 using ::android::sp;
40 using ::android::hardware::hidl_vec;
41 using ::android::hardware::Return;
42 using ::android::hardware::automotive::vehicle::toInt;
43 using ::android::hardware::automotive::vehicle::V2_0::IVehicle;
44 using ::android::hardware::automotive::vehicle::V2_0::IVehicleCallback;
45 using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
46 using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
47 using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
48 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
49 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
50
51 using ::testing::UnorderedElementsAre;
52
53 class MockVhal final : public IVehicle {
54 public:
getAllPropConfigs(IVehicle::getAllPropConfigs_cb callback)55 Return<void> getAllPropConfigs(IVehicle::getAllPropConfigs_cb callback) override {
56 callback(mPropConfigs);
57 return {};
58 }
59
getPropConfigs(const hidl_vec<int32_t> & props,IVehicle::getPropConfigs_cb callback)60 Return<void> getPropConfigs(const hidl_vec<int32_t>& props,
61 IVehicle::getPropConfigs_cb callback) override {
62 mGetPropConfigsProps = props;
63 callback(mStatus, mPropConfigs);
64 return {};
65 }
66
get(const VehiclePropValue & requestPropValue,IVehicle::get_cb callback)67 Return<void> get(const VehiclePropValue& requestPropValue, IVehicle::get_cb callback) override {
68 mRequestPropValue = requestPropValue;
69 callback(mStatus, mPropValue);
70 return {};
71 }
72
set(const VehiclePropValue & value)73 Return<StatusCode> set(const VehiclePropValue& value) override {
74 mRequestPropValue = value;
75 return mStatus;
76 }
77
subscribe(const sp<IVehicleCallback> & callback,const hidl_vec<SubscribeOptions> & options)78 Return<StatusCode> subscribe(const sp<IVehicleCallback>& callback,
79 const hidl_vec<SubscribeOptions>& options) override {
80 mSubscribedCallback = callback;
81 mSubscribeOptions = options;
82 return mStatus;
83 }
84
unsubscribe(const sp<IVehicleCallback> & callback,int32_t propId)85 Return<StatusCode> unsubscribe([[maybe_unused]] const sp<IVehicleCallback>& callback,
86 int32_t propId) override {
87 mUnsubscribedPropIds.push_back(propId);
88 return mStatus;
89 }
90
debugDump(IVehicle::debugDump_cb callback)91 Return<void> debugDump([[maybe_unused]] IVehicle::debugDump_cb callback) override { return {}; }
92
93 // Test functions
94
setPropConfigs(std::vector<VehiclePropConfig> configs)95 void setPropConfigs(std::vector<VehiclePropConfig> configs) { mPropConfigs = configs; }
96
setStatus(StatusCode status)97 void setStatus(StatusCode status) { mStatus = status; }
98
setVehiclePropValue(VehiclePropValue value)99 void setVehiclePropValue(VehiclePropValue value) { mPropValue = value; }
100
getGetPropConfigsProps()101 std::vector<int32_t> getGetPropConfigsProps() { return mGetPropConfigsProps; }
102
getRequestPropValue()103 VehiclePropValue getRequestPropValue() { return mRequestPropValue; }
104
getSubscribeOptions()105 std::vector<SubscribeOptions> getSubscribeOptions() { return mSubscribeOptions; }
106
getUnsubscribedPropId()107 int32_t getUnsubscribedPropId() { return mUnsubscribedPropIds[0]; }
108
getUnsubscribedPropIds()109 std::vector<int32_t> getUnsubscribedPropIds() { return mUnsubscribedPropIds; }
110
resetUnsubscribedPropIds()111 void resetUnsubscribedPropIds() { mUnsubscribedPropIds.clear(); }
112
triggerOnPropertyEvent(const std::vector<VehiclePropValue> & values)113 void triggerOnPropertyEvent(const std::vector<VehiclePropValue>& values) {
114 mSubscribedCallback->onPropertyEvent(values);
115 }
116
triggerSetErrorEvent(StatusCode status,int32_t propId,int32_t areaId)117 void triggerSetErrorEvent(StatusCode status, int32_t propId, int32_t areaId) {
118 mSubscribedCallback->onPropertySetError(status, propId, areaId);
119 }
120
121 private:
122 std::vector<VehiclePropConfig> mPropConfigs;
123 StatusCode mStatus = StatusCode::OK;
124 VehiclePropValue mPropValue;
125
126 std::vector<int32_t> mGetPropConfigsProps;
127 VehiclePropValue mRequestPropValue;
128 sp<IVehicleCallback> mSubscribedCallback;
129 std::vector<SubscribeOptions> mSubscribeOptions;
130 std::vector<int32_t> mUnsubscribedPropIds;
131 };
132
133 class MockSubscriptionCallback final : public ISubscriptionCallback {
134 public:
onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>> & values)135 void onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>>& values) override {
136 for (const auto& value : values) {
137 mEventPropIds.push_back(value->getPropId());
138 }
139 }
onPropertySetError(const std::vector<HalPropError> & errors)140 void onPropertySetError(const std::vector<HalPropError>& errors) override { mErrors = errors; }
141
getEventPropIds()142 std::vector<int32_t> getEventPropIds() { return mEventPropIds; }
143
getErrors()144 std::vector<HalPropError> getErrors() { return mErrors; }
145
146 private:
147 std::vector<int32_t> mEventPropIds;
148 std::vector<HalPropError> mErrors;
149 };
150
151 class HidlVhalClientTest : public ::testing::Test {
152 protected:
153 constexpr static int32_t TEST_PROP_ID = 1;
154 constexpr static int32_t TEST_AREA_ID = 2;
155 constexpr static int32_t TEST_PROP_ID_2 = 3;
156 constexpr static int32_t TEST_AREA_ID_2 = 4;
157
158 const VehiclePropValue TEST_VALUE{
159 .prop = TEST_PROP_ID,
160 .areaId = TEST_AREA_ID,
161 .value.int32Values = {1},
162 };
163
SetUp()164 void SetUp() override {
165 mVhal = new MockVhal();
166 mVhalClient = std::make_unique<HidlVhalClient>(mVhal);
167 }
168
getVhal()169 MockVhal* getVhal() { return mVhal.get(); }
170
getClient()171 HidlVhalClient* getClient() { return mVhalClient.get(); }
172
resetClient()173 void resetClient() { mVhalClient.reset(); }
174
triggerBinderDied()175 void triggerBinderDied() { mVhalClient->onBinderDied(); }
176
177 private:
178 sp<MockVhal> mVhal;
179 std::unique_ptr<HidlVhalClient> mVhalClient;
180 };
181
TEST_F(HidlVhalClientTest,testIsAidl)182 TEST_F(HidlVhalClientTest, testIsAidl) {
183 ASSERT_FALSE(getClient()->isAidlVhal());
184 }
185
TEST_F(HidlVhalClientTest,testGetValue)186 TEST_F(HidlVhalClientTest, testGetValue) {
187 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
188 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
189 bool gotResult = false;
190 bool* gotResultPtr = &gotResult;
191 auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
192 [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
193 *resultPtr = std::move(r);
194 *gotResultPtr = true;
195 });
196 getVhal()->setVehiclePropValue(TEST_VALUE);
197
198 getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
199
200 ASSERT_TRUE(gotResult);
201 ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
202 ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
203 ASSERT_TRUE(result.ok());
204 auto gotValue = std::move(result.value());
205 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
206 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
207 ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::AVAILABLE);
208 ASSERT_EQ(gotValue->getInt32Values(), std::vector<int32_t>({1}));
209 }
210
TEST_F(HidlVhalClientTest,testGetValueUnavailableStatus)211 TEST_F(HidlVhalClientTest, testGetValueUnavailableStatus) {
212 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
213 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
214 bool gotResult = false;
215 bool* gotResultPtr = &gotResult;
216 auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
217 [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
218 *resultPtr = std::move(r);
219 *gotResultPtr = true;
220 });
221 getVhal()->setVehiclePropValue(VehiclePropValue{
222 .prop = TEST_PROP_ID,
223 .areaId = TEST_AREA_ID,
224 .status = android::hardware::automotive::vehicle::V2_0::VehiclePropertyStatus::
225 UNAVAILABLE,
226 });
227
228 getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
229
230 ASSERT_TRUE(gotResult);
231 ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
232 ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
233 ASSERT_TRUE(result.ok());
234 auto gotValue = std::move(result.value());
235 ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
236 ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
237 ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::UNAVAILABLE);
238 }
239
TEST_F(HidlVhalClientTest,testGetValueError)240 TEST_F(HidlVhalClientTest, testGetValueError) {
241 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
242
243 VhalClientResult<std::unique_ptr<IHalPropValue>> result;
244 VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
245 bool gotResult = false;
246 bool* gotResultPtr = &gotResult;
247 auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
248 [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
249 *resultPtr = std::move(r);
250 *gotResultPtr = true;
251 });
252
253 getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
254
255 ASSERT_TRUE(gotResult);
256 ASSERT_FALSE(result.ok());
257 }
258
TEST_F(HidlVhalClientTest,testSetValue)259 TEST_F(HidlVhalClientTest, testSetValue) {
260 VhalClientResult<void> result;
261 VhalClientResult<void>* resultPtr = &result;
262 bool gotResult = false;
263 bool* gotResultPtr = &gotResult;
264 auto callback = std::make_shared<HidlVhalClient::SetValueCallbackFunc>(
265 [resultPtr, gotResultPtr](VhalClientResult<void> r) {
266 *resultPtr = std::move(r);
267 *gotResultPtr = true;
268 });
269
270 getClient()->setValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
271
272 ASSERT_TRUE(gotResult);
273 ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
274 ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
275 ASSERT_TRUE(result.ok());
276 }
TEST_F(HidlVhalClientTest,testSetValueError)277 TEST_F(HidlVhalClientTest, testSetValueError) {
278 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
279
280 VhalClientResult<void> result;
281 VhalClientResult<void>* resultPtr = &result;
282 bool gotResult = false;
283 bool* gotResultPtr = &gotResult;
284 auto callback = std::make_shared<HidlVhalClient::SetValueCallbackFunc>(
285 [resultPtr, gotResultPtr](VhalClientResult<void> r) {
286 *resultPtr = std::move(r);
287 *gotResultPtr = true;
288 });
289
290 getClient()->setValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
291
292 ASSERT_TRUE(gotResult);
293 ASSERT_FALSE(result.ok());
294 }
295
TEST_F(HidlVhalClientTest,testAddOnBinderDiedCallback)296 TEST_F(HidlVhalClientTest, testAddOnBinderDiedCallback) {
297 struct Result {
298 bool callbackOneCalled = false;
299 bool callbackTwoCalled = false;
300 } result;
301
302 getClient()->addOnBinderDiedCallback(std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
303 [&result] { result.callbackOneCalled = true; }));
304 getClient()->addOnBinderDiedCallback(std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
305 [&result] { result.callbackTwoCalled = true; }));
306 triggerBinderDied();
307
308 ASSERT_TRUE(result.callbackOneCalled);
309 ASSERT_TRUE(result.callbackTwoCalled);
310 }
311
TEST_F(HidlVhalClientTest,testOnBinderDied_noDeadLock)312 TEST_F(HidlVhalClientTest, testOnBinderDied_noDeadLock) {
313 getClient()->addOnBinderDiedCallback(
314 std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>([this] {
315 // This will trigger the destructor for HidlVhalClient. This must not cause dead
316 // lock.
317 resetClient();
318 }));
319
320 triggerBinderDied();
321 }
322
TEST_F(HidlVhalClientTest,testRemoveOnBinderDiedCallback)323 TEST_F(HidlVhalClientTest, testRemoveOnBinderDiedCallback) {
324 struct Result {
325 bool callbackOneCalled = false;
326 bool callbackTwoCalled = false;
327 } result;
328
329 auto callbackOne = std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
330 [&result] { result.callbackOneCalled = true; });
331 auto callbackTwo = std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
332 [&result] { result.callbackTwoCalled = true; });
333 getClient()->addOnBinderDiedCallback(callbackOne);
334 getClient()->addOnBinderDiedCallback(callbackTwo);
335 getClient()->removeOnBinderDiedCallback(callbackOne);
336 triggerBinderDied();
337
338 ASSERT_FALSE(result.callbackOneCalled);
339 ASSERT_TRUE(result.callbackTwoCalled);
340 }
341
TEST_F(HidlVhalClientTest,testGetAllPropConfigs)342 TEST_F(HidlVhalClientTest, testGetAllPropConfigs) {
343 getVhal()->setPropConfigs({
344 VehiclePropConfig{
345 .prop = TEST_PROP_ID,
346 .areaConfigs = {{
347 .areaId = TEST_AREA_ID,
348 .minInt32Value = 0,
349 .maxInt32Value = 1,
350 },
351 {
352 .areaId = TEST_AREA_ID_2,
353 .minInt32Value = 2,
354 .maxInt32Value = 3,
355 }},
356 },
357 VehiclePropConfig{
358 .prop = TEST_PROP_ID_2,
359 },
360 });
361
362 auto result = getClient()->getAllPropConfigs();
363
364 ASSERT_TRUE(result.ok());
365 std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
366
367 ASSERT_EQ(configs.size(), static_cast<size_t>(2));
368 ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
369 ASSERT_EQ(configs[0]->getAccess(), 0);
370 ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
371
372 const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
373 ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
374 ASSERT_EQ(areaConfig0->getAccess(), 0);
375 ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
376 ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
377 ASSERT_FALSE(areaConfig0->isVariableUpdateRateSupported());
378
379 const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
380 ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
381 ASSERT_EQ(areaConfig1->getAccess(), 0);
382 ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
383 ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
384 ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
385
386 ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
387 ASSERT_EQ(configs[1]->getAccess(), 0);
388 ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
389
390 const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
391 ASSERT_EQ(areaConfig2->getAreaId(), 0);
392 ASSERT_EQ(areaConfig2->getAccess(), 0);
393 ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
394 }
395
TEST_F(HidlVhalClientTest,testGetPropConfigs)396 TEST_F(HidlVhalClientTest, testGetPropConfigs) {
397 getVhal()->setPropConfigs({
398 VehiclePropConfig{
399 .prop = TEST_PROP_ID,
400 .areaConfigs = {{
401 .areaId = TEST_AREA_ID,
402 .minInt32Value = 0,
403 .maxInt32Value = 1,
404 },
405 {
406 .areaId = TEST_AREA_ID_2,
407 .minInt32Value = 2,
408 .maxInt32Value = 3,
409 }},
410 },
411 VehiclePropConfig{
412 .prop = TEST_PROP_ID_2,
413 },
414 });
415
416 std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
417 auto result = getClient()->getPropConfigs(propIds);
418
419 ASSERT_EQ(getVhal()->getGetPropConfigsProps(), propIds);
420 ASSERT_TRUE(result.ok());
421 std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
422
423 ASSERT_EQ(configs.size(), static_cast<size_t>(2));
424 ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
425 ASSERT_EQ(configs[0]->getAccess(), 0);
426 ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
427
428 const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
429 ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
430 ASSERT_EQ(areaConfig0->getAccess(), 0);
431 ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
432 ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
433 ASSERT_FALSE(areaConfig0->isVariableUpdateRateSupported());
434
435 const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
436 ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
437 ASSERT_EQ(areaConfig1->getAccess(), 0);
438 ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
439 ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
440 ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
441
442 ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
443 ASSERT_EQ(configs[1]->getAccess(), 0);
444 ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
445
446 const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
447 ASSERT_EQ(areaConfig2->getAreaId(), 0);
448 ASSERT_EQ(areaConfig2->getAccess(), 0);
449 ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
450 }
451
TEST_F(HidlVhalClientTest,testGetPropConfigsError)452 TEST_F(HidlVhalClientTest, testGetPropConfigsError) {
453 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
454
455 std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
456 auto result = getClient()->getPropConfigs(propIds);
457
458 ASSERT_FALSE(result.ok());
459 }
460
TEST_F(HidlVhalClientTest,testSubscribe)461 TEST_F(HidlVhalClientTest, testSubscribe) {
462 std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
463 {
464 .propId = TEST_PROP_ID,
465 .areaIds = {TEST_AREA_ID},
466 .sampleRate = 1.0,
467 },
468 {
469 .propId = TEST_PROP_ID_2,
470 .sampleRate = 2.0,
471 },
472 };
473 std::vector<SubscribeOptions> hidlOptions = {
474 {
475 .propId = TEST_PROP_ID,
476 .flags = SubscribeFlags::EVENTS_FROM_CAR,
477 .sampleRate = 1.0,
478 },
479 {
480 .propId = TEST_PROP_ID_2,
481 .flags = SubscribeFlags::EVENTS_FROM_CAR,
482 .sampleRate = 2.0,
483 },
484 };
485
486 auto callback = std::make_shared<MockSubscriptionCallback>();
487 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
488 auto result = subscriptionClient->subscribe(options);
489
490 ASSERT_TRUE(result.ok());
491 ASSERT_EQ(getVhal()->getSubscribeOptions(), hidlOptions);
492
493 getVhal()->triggerOnPropertyEvent(std::vector<VehiclePropValue>{
494 {
495 .prop = TEST_PROP_ID,
496 .areaId = TEST_AREA_ID,
497 .value.int32Values = {1},
498 },
499 });
500
501 ASSERT_EQ(callback->getEventPropIds(), std::vector<int32_t>({TEST_PROP_ID}));
502
503 getVhal()->triggerSetErrorEvent(StatusCode::INTERNAL_ERROR, TEST_PROP_ID, TEST_AREA_ID);
504
505 auto errors = callback->getErrors();
506 ASSERT_EQ(errors.size(), static_cast<size_t>(1));
507 ASSERT_EQ(errors[0].propId, TEST_PROP_ID);
508 ASSERT_EQ(errors[0].areaId, TEST_AREA_ID);
509 ASSERT_EQ(errors[0].status,
510 ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
511 }
512
TEST_F(HidlVhalClientTest,testSubscribeError)513 TEST_F(HidlVhalClientTest, testSubscribeError) {
514 std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
515 {
516 .propId = TEST_PROP_ID,
517 .areaIds = {TEST_AREA_ID},
518 .sampleRate = 1.0,
519 },
520 {
521 .propId = TEST_PROP_ID_2,
522 .sampleRate = 2.0,
523 },
524 };
525
526 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
527 auto callback = std::make_shared<MockSubscriptionCallback>();
528 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
529 auto result = subscriptionClient->subscribe(options);
530
531 ASSERT_FALSE(result.ok());
532 }
533
TEST_F(HidlVhalClientTest,testUnubscribe)534 TEST_F(HidlVhalClientTest, testUnubscribe) {
535 auto callback = std::make_shared<MockSubscriptionCallback>();
536 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
537 auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
538
539 ASSERT_TRUE(result.ok());
540 ASSERT_EQ(getVhal()->getUnsubscribedPropId(), TEST_PROP_ID);
541 }
542
TEST_F(HidlVhalClientTest,testUnubscribeError)543 TEST_F(HidlVhalClientTest, testUnubscribeError) {
544 getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
545 auto callback = std::make_shared<MockSubscriptionCallback>();
546 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
547 auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
548
549 ASSERT_FALSE(result.ok());
550 }
551
TEST_F(HidlVhalClientTest,testUnsubscribeAll)552 TEST_F(HidlVhalClientTest, testUnsubscribeAll) {
553 std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
554 {
555 .propId = TEST_PROP_ID,
556 .areaIds = {TEST_AREA_ID},
557 .sampleRate = 1.0,
558 },
559 {
560 .propId = TEST_PROP_ID_2,
561 .sampleRate = 2.0,
562 },
563 };
564
565 auto callback = std::make_shared<MockSubscriptionCallback>();
566 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
567 subscriptionClient->subscribe(options);
568
569 subscriptionClient->unsubscribeAll();
570
571 ASSERT_THAT(getVhal()->getUnsubscribedPropIds(),
572 UnorderedElementsAre(TEST_PROP_ID, TEST_PROP_ID_2));
573
574 getVhal()->resetUnsubscribedPropIds();
575 subscriptionClient->unsubscribeAll();
576
577 ASSERT_EQ(getVhal()->getUnsubscribedPropIds().size(), 0u);
578 }
579
TEST_F(HidlVhalClientTest,testUnsubscribeAll_AfterUnsubscribe)580 TEST_F(HidlVhalClientTest, testUnsubscribeAll_AfterUnsubscribe) {
581 std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
582 {
583 .propId = TEST_PROP_ID,
584 .areaIds = {TEST_AREA_ID},
585 .sampleRate = 1.0,
586 },
587 {
588 .propId = TEST_PROP_ID_2,
589 .sampleRate = 2.0,
590 },
591 };
592
593 auto callback = std::make_shared<MockSubscriptionCallback>();
594 auto subscriptionClient = getClient()->getSubscriptionClient(callback);
595 subscriptionClient->subscribe(options);
596 subscriptionClient->unsubscribe({TEST_PROP_ID});
597 getVhal()->resetUnsubscribedPropIds();
598
599 subscriptionClient->unsubscribeAll();
600 ASSERT_THAT(getVhal()->getUnsubscribedPropIds(), UnorderedElementsAre(TEST_PROP_ID_2));
601 }
602
TEST_F(HidlVhalClientTest,testGetRemoteInterfaceVersion)603 TEST_F(HidlVhalClientTest, testGetRemoteInterfaceVersion) {
604 // getRemoteInterfaceVersion will always return 0 for HIDL client.
605 ASSERT_EQ(getClient()->getRemoteInterfaceVersion(), 0);
606 }
607
TEST_F(HidlVhalClientTest,testHidlHalPropValueClone_valueIsTheSame)608 TEST_F(HidlVhalClientTest, testHidlHalPropValueClone_valueIsTheSame) {
609 VehiclePropValue testProp{.prop = TEST_PROP_ID,
610 .areaId = TEST_AREA_ID,
611 .value = {
612 .int32Values = {1, 2},
613 .floatValues = {1.1, 2.2},
614 }};
615 auto testPropCopy = testProp;
616 std::unique_ptr<IHalPropValue> halPropValue =
617 std::make_unique<HidlHalPropValue>(std::move(testPropCopy));
618 auto halPropValueClone = halPropValue->clone();
619
620 EXPECT_EQ(halPropValueClone->getPropId(), TEST_PROP_ID);
621 EXPECT_EQ(halPropValueClone->getAreaId(), TEST_AREA_ID);
622 EXPECT_EQ(halPropValueClone->getInt32Values(), std::vector<int32_t>({1, 2}));
623 EXPECT_EQ(halPropValueClone->getFloatValues(), std::vector<float>({1.1, 2.2}));
624 }
625
TEST_F(HidlVhalClientTest,testHidlHalPropValueClone_modifyCloneDoesNotAffectOrig)626 TEST_F(HidlVhalClientTest, testHidlHalPropValueClone_modifyCloneDoesNotAffectOrig) {
627 std::vector<int32_t> int32Values1 = {1, 2};
628 std::vector<float> floatValues1 = {1.1, 2.2};
629 std::vector<int32_t> int32Values2 = {5, 4, 3, 2, 1};
630 std::vector<float> floatValues2 = {3.3, 2.2, 1.1};
631
632 VehiclePropValue testProp{.prop = TEST_PROP_ID,
633 .areaId = TEST_AREA_ID,
634 .value = {
635 .int32Values = int32Values1,
636 .floatValues = floatValues1,
637 }};
638 auto testPropCopy = testProp;
639 std::unique_ptr<IHalPropValue> halPropValue =
640 std::make_unique<HidlHalPropValue>(std::move(testPropCopy));
641 auto halPropValueClone = halPropValue->clone();
642
643 halPropValueClone->setInt32Values(int32Values2);
644 halPropValueClone->setFloatValues(floatValues2);
645
646 EXPECT_EQ(halPropValue->getInt32Values(), int32Values1);
647 EXPECT_EQ(halPropValue->getFloatValues(), floatValues1);
648 EXPECT_EQ(halPropValueClone->getInt32Values(), int32Values2);
649 EXPECT_EQ(halPropValueClone->getFloatValues(), floatValues2);
650 }
651
TEST_F(HidlVhalClientTest,testGetMinMaxSupportedValue_notSupported)652 TEST_F(HidlVhalClientTest, testGetMinMaxSupportedValue_notSupported) {
653 PropIdAreaId propIdAreaId = {
654 .propId = 1,
655 .areaId = 2,
656 };
657
658 auto result = getClient()->getMinMaxSupportedValue({propIdAreaId});
659
660 ASSERT_FALSE(result.ok());
661 ASSERT_EQ(result.error().code().value(), ErrorCode::NOT_SUPPORTED);
662 }
663
TEST_F(HidlVhalClientTest,testGetSupportedValuesLists_notSupported)664 TEST_F(HidlVhalClientTest, testGetSupportedValuesLists_notSupported) {
665 PropIdAreaId propIdAreaId = {
666 .propId = 1,
667 .areaId = 2,
668 };
669
670 auto result = getClient()->getSupportedValuesLists({propIdAreaId});
671
672 ASSERT_FALSE(result.ok());
673 ASSERT_EQ(result.error().code().value(), ErrorCode::NOT_SUPPORTED);
674 }
675
676 } // namespace hidl_test
677 } // namespace vhal
678 } // namespace automotive
679 } // namespace frameworks
680 } // namespace android
681