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