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