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 
triggerBinderDied()165     void triggerBinderDied() { mVhalClient->onBinderDied(); }
166 
167 private:
168     sp<MockVhal> mVhal;
169     std::unique_ptr<HidlVhalClient> mVhalClient;
170 };
171 
TEST_F(HidlVhalClientTest,testIsAidl)172 TEST_F(HidlVhalClientTest, testIsAidl) {
173     ASSERT_FALSE(getClient()->isAidlVhal());
174 }
175 
TEST_F(HidlVhalClientTest,testGetValue)176 TEST_F(HidlVhalClientTest, testGetValue) {
177     VhalClientResult<std::unique_ptr<IHalPropValue>> result;
178     VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
179     bool gotResult = false;
180     bool* gotResultPtr = &gotResult;
181     auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
182             [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
183                 *resultPtr = std::move(r);
184                 *gotResultPtr = true;
185             });
186     getVhal()->setVehiclePropValue(TEST_VALUE);
187 
188     getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
189 
190     ASSERT_TRUE(gotResult);
191     ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
192     ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
193     ASSERT_TRUE(result.ok());
194     auto gotValue = std::move(result.value());
195     ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
196     ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
197     ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::AVAILABLE);
198     ASSERT_EQ(gotValue->getInt32Values(), std::vector<int32_t>({1}));
199 }
200 
TEST_F(HidlVhalClientTest,testGetValueUnavailableStatus)201 TEST_F(HidlVhalClientTest, testGetValueUnavailableStatus) {
202     VhalClientResult<std::unique_ptr<IHalPropValue>> result;
203     VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
204     bool gotResult = false;
205     bool* gotResultPtr = &gotResult;
206     auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
207             [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
208                 *resultPtr = std::move(r);
209                 *gotResultPtr = true;
210             });
211     getVhal()->setVehiclePropValue(VehiclePropValue{
212             .prop = TEST_PROP_ID,
213             .areaId = TEST_AREA_ID,
214             .status = android::hardware::automotive::vehicle::V2_0::VehiclePropertyStatus::
215                     UNAVAILABLE,
216     });
217 
218     getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
219 
220     ASSERT_TRUE(gotResult);
221     ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
222     ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
223     ASSERT_TRUE(result.ok());
224     auto gotValue = std::move(result.value());
225     ASSERT_EQ(gotValue->getPropId(), TEST_PROP_ID);
226     ASSERT_EQ(gotValue->getAreaId(), TEST_AREA_ID);
227     ASSERT_EQ(gotValue->getStatus(), VehiclePropertyStatus::UNAVAILABLE);
228 }
229 
TEST_F(HidlVhalClientTest,testGetValueError)230 TEST_F(HidlVhalClientTest, testGetValueError) {
231     getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
232 
233     VhalClientResult<std::unique_ptr<IHalPropValue>> result;
234     VhalClientResult<std::unique_ptr<IHalPropValue>>* resultPtr = &result;
235     bool gotResult = false;
236     bool* gotResultPtr = &gotResult;
237     auto callback = std::make_shared<HidlVhalClient::GetValueCallbackFunc>(
238             [resultPtr, gotResultPtr](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
239                 *resultPtr = std::move(r);
240                 *gotResultPtr = true;
241             });
242 
243     getClient()->getValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
244 
245     ASSERT_TRUE(gotResult);
246     ASSERT_FALSE(result.ok());
247 }
248 
TEST_F(HidlVhalClientTest,testSetValue)249 TEST_F(HidlVhalClientTest, testSetValue) {
250     VhalClientResult<void> result;
251     VhalClientResult<void>* resultPtr = &result;
252     bool gotResult = false;
253     bool* gotResultPtr = &gotResult;
254     auto callback = std::make_shared<HidlVhalClient::SetValueCallbackFunc>(
255             [resultPtr, gotResultPtr](VhalClientResult<void> r) {
256                 *resultPtr = std::move(r);
257                 *gotResultPtr = true;
258             });
259 
260     getClient()->setValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
261 
262     ASSERT_TRUE(gotResult);
263     ASSERT_EQ(getVhal()->getRequestPropValue().prop, TEST_PROP_ID);
264     ASSERT_EQ(getVhal()->getRequestPropValue().areaId, TEST_AREA_ID);
265     ASSERT_TRUE(result.ok());
266 }
TEST_F(HidlVhalClientTest,testSetValueError)267 TEST_F(HidlVhalClientTest, testSetValueError) {
268     getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
269 
270     VhalClientResult<void> result;
271     VhalClientResult<void>* resultPtr = &result;
272     bool gotResult = false;
273     bool* gotResultPtr = &gotResult;
274     auto callback = std::make_shared<HidlVhalClient::SetValueCallbackFunc>(
275             [resultPtr, gotResultPtr](VhalClientResult<void> r) {
276                 *resultPtr = std::move(r);
277                 *gotResultPtr = true;
278             });
279 
280     getClient()->setValue(HidlHalPropValue(TEST_PROP_ID, TEST_AREA_ID), callback);
281 
282     ASSERT_TRUE(gotResult);
283     ASSERT_FALSE(result.ok());
284 }
285 
TEST_F(HidlVhalClientTest,testAddOnBinderDiedCallback)286 TEST_F(HidlVhalClientTest, testAddOnBinderDiedCallback) {
287     struct Result {
288         bool callbackOneCalled = false;
289         bool callbackTwoCalled = false;
290     } result;
291 
292     getClient()->addOnBinderDiedCallback(std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
293             [&result] { result.callbackOneCalled = true; }));
294     getClient()->addOnBinderDiedCallback(std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
295             [&result] { result.callbackTwoCalled = true; }));
296     triggerBinderDied();
297 
298     ASSERT_TRUE(result.callbackOneCalled);
299     ASSERT_TRUE(result.callbackTwoCalled);
300 }
301 
TEST_F(HidlVhalClientTest,testRemoveOnBinderDiedCallback)302 TEST_F(HidlVhalClientTest, testRemoveOnBinderDiedCallback) {
303     struct Result {
304         bool callbackOneCalled = false;
305         bool callbackTwoCalled = false;
306     } result;
307 
308     auto callbackOne = std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
309             [&result] { result.callbackOneCalled = true; });
310     auto callbackTwo = std::make_shared<HidlVhalClient::OnBinderDiedCallbackFunc>(
311             [&result] { result.callbackTwoCalled = true; });
312     getClient()->addOnBinderDiedCallback(callbackOne);
313     getClient()->addOnBinderDiedCallback(callbackTwo);
314     getClient()->removeOnBinderDiedCallback(callbackOne);
315     triggerBinderDied();
316 
317     ASSERT_FALSE(result.callbackOneCalled);
318     ASSERT_TRUE(result.callbackTwoCalled);
319 }
320 
TEST_F(HidlVhalClientTest,testGetAllPropConfigs)321 TEST_F(HidlVhalClientTest, testGetAllPropConfigs) {
322     getVhal()->setPropConfigs({
323             VehiclePropConfig{
324                     .prop = TEST_PROP_ID,
325                     .areaConfigs = {{
326                                             .areaId = TEST_AREA_ID,
327                                             .minInt32Value = 0,
328                                             .maxInt32Value = 1,
329                                     },
330                                     {
331                                             .areaId = TEST_AREA_ID_2,
332                                             .minInt32Value = 2,
333                                             .maxInt32Value = 3,
334                                     }},
335             },
336             VehiclePropConfig{
337                     .prop = TEST_PROP_ID_2,
338             },
339     });
340 
341     auto result = getClient()->getAllPropConfigs();
342 
343     ASSERT_TRUE(result.ok());
344     std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
345 
346     ASSERT_EQ(configs.size(), static_cast<size_t>(2));
347     ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
348     ASSERT_EQ(configs[0]->getAccess(), 0);
349     ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
350 
351     const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
352     ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
353     ASSERT_EQ(areaConfig0->getAccess(), 0);
354     ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
355     ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
356     ASSERT_FALSE(areaConfig0->isVariableUpdateRateSupported());
357 
358     const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
359     ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
360     ASSERT_EQ(areaConfig1->getAccess(), 0);
361     ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
362     ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
363     ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
364 
365     ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
366     ASSERT_EQ(configs[1]->getAccess(), 0);
367     ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
368 
369     const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
370     ASSERT_EQ(areaConfig2->getAreaId(), 0);
371     ASSERT_EQ(areaConfig2->getAccess(), 0);
372     ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
373 }
374 
TEST_F(HidlVhalClientTest,testGetPropConfigs)375 TEST_F(HidlVhalClientTest, testGetPropConfigs) {
376     getVhal()->setPropConfigs({
377             VehiclePropConfig{
378                     .prop = TEST_PROP_ID,
379                     .areaConfigs = {{
380                                             .areaId = TEST_AREA_ID,
381                                             .minInt32Value = 0,
382                                             .maxInt32Value = 1,
383                                     },
384                                     {
385                                             .areaId = TEST_AREA_ID_2,
386                                             .minInt32Value = 2,
387                                             .maxInt32Value = 3,
388                                     }},
389             },
390             VehiclePropConfig{
391                     .prop = TEST_PROP_ID_2,
392             },
393     });
394 
395     std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
396     auto result = getClient()->getPropConfigs(propIds);
397 
398     ASSERT_EQ(getVhal()->getGetPropConfigsProps(), propIds);
399     ASSERT_TRUE(result.ok());
400     std::vector<std::unique_ptr<IHalPropConfig>> configs = std::move(result.value());
401 
402     ASSERT_EQ(configs.size(), static_cast<size_t>(2));
403     ASSERT_EQ(configs[0]->getPropId(), TEST_PROP_ID);
404     ASSERT_EQ(configs[0]->getAccess(), 0);
405     ASSERT_EQ(configs[0]->getAreaConfigSize(), static_cast<size_t>(2));
406 
407     const std::unique_ptr<IHalAreaConfig>& areaConfig0 = configs[0]->getAreaConfigs()[0];
408     ASSERT_EQ(areaConfig0->getAreaId(), TEST_AREA_ID);
409     ASSERT_EQ(areaConfig0->getAccess(), 0);
410     ASSERT_EQ(areaConfig0->getMinInt32Value(), 0);
411     ASSERT_EQ(areaConfig0->getMaxInt32Value(), 1);
412     ASSERT_FALSE(areaConfig0->isVariableUpdateRateSupported());
413 
414     const std::unique_ptr<IHalAreaConfig>& areaConfig1 = configs[0]->getAreaConfigs()[1];
415     ASSERT_EQ(areaConfig1->getAreaId(), TEST_AREA_ID_2);
416     ASSERT_EQ(areaConfig1->getAccess(), 0);
417     ASSERT_EQ(areaConfig1->getMinInt32Value(), 2);
418     ASSERT_EQ(areaConfig1->getMaxInt32Value(), 3);
419     ASSERT_FALSE(areaConfig1->isVariableUpdateRateSupported());
420 
421     ASSERT_EQ(configs[1]->getPropId(), TEST_PROP_ID_2);
422     ASSERT_EQ(configs[1]->getAccess(), 0);
423     ASSERT_EQ(configs[1]->getAreaConfigSize(), static_cast<size_t>(1));
424 
425     const std::unique_ptr<IHalAreaConfig>& areaConfig2 = configs[1]->getAreaConfigs()[0];
426     ASSERT_EQ(areaConfig2->getAreaId(), 0);
427     ASSERT_EQ(areaConfig2->getAccess(), 0);
428     ASSERT_FALSE(areaConfig2->isVariableUpdateRateSupported());
429 }
430 
TEST_F(HidlVhalClientTest,testGetPropConfigsError)431 TEST_F(HidlVhalClientTest, testGetPropConfigsError) {
432     getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
433 
434     std::vector<int32_t> propIds = {TEST_PROP_ID, TEST_PROP_ID_2};
435     auto result = getClient()->getPropConfigs(propIds);
436 
437     ASSERT_FALSE(result.ok());
438 }
439 
TEST_F(HidlVhalClientTest,testSubscribe)440 TEST_F(HidlVhalClientTest, testSubscribe) {
441     std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
442             {
443                     .propId = TEST_PROP_ID,
444                     .areaIds = {TEST_AREA_ID},
445                     .sampleRate = 1.0,
446             },
447             {
448                     .propId = TEST_PROP_ID_2,
449                     .sampleRate = 2.0,
450             },
451     };
452     std::vector<SubscribeOptions> hidlOptions = {
453             {
454                     .propId = TEST_PROP_ID,
455                     .flags = SubscribeFlags::EVENTS_FROM_CAR,
456                     .sampleRate = 1.0,
457             },
458             {
459                     .propId = TEST_PROP_ID_2,
460                     .flags = SubscribeFlags::EVENTS_FROM_CAR,
461                     .sampleRate = 2.0,
462             },
463     };
464 
465     auto callback = std::make_shared<MockSubscriptionCallback>();
466     auto subscriptionClient = getClient()->getSubscriptionClient(callback);
467     auto result = subscriptionClient->subscribe(options);
468 
469     ASSERT_TRUE(result.ok());
470     ASSERT_EQ(getVhal()->getSubscribeOptions(), hidlOptions);
471 
472     getVhal()->triggerOnPropertyEvent(std::vector<VehiclePropValue>{
473             {
474                     .prop = TEST_PROP_ID,
475                     .areaId = TEST_AREA_ID,
476                     .value.int32Values = {1},
477             },
478     });
479 
480     ASSERT_EQ(callback->getEventPropIds(), std::vector<int32_t>({TEST_PROP_ID}));
481 
482     getVhal()->triggerSetErrorEvent(StatusCode::INTERNAL_ERROR, TEST_PROP_ID, TEST_AREA_ID);
483 
484     auto errors = callback->getErrors();
485     ASSERT_EQ(errors.size(), static_cast<size_t>(1));
486     ASSERT_EQ(errors[0].propId, TEST_PROP_ID);
487     ASSERT_EQ(errors[0].areaId, TEST_AREA_ID);
488     ASSERT_EQ(errors[0].status,
489               ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
490 }
491 
TEST_F(HidlVhalClientTest,testSubscribeError)492 TEST_F(HidlVhalClientTest, testSubscribeError) {
493     std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions> options = {
494             {
495                     .propId = TEST_PROP_ID,
496                     .areaIds = {TEST_AREA_ID},
497                     .sampleRate = 1.0,
498             },
499             {
500                     .propId = TEST_PROP_ID_2,
501                     .sampleRate = 2.0,
502             },
503     };
504 
505     getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
506     auto callback = std::make_shared<MockSubscriptionCallback>();
507     auto subscriptionClient = getClient()->getSubscriptionClient(callback);
508     auto result = subscriptionClient->subscribe(options);
509 
510     ASSERT_FALSE(result.ok());
511 }
512 
TEST_F(HidlVhalClientTest,testUnubscribe)513 TEST_F(HidlVhalClientTest, testUnubscribe) {
514     auto callback = std::make_shared<MockSubscriptionCallback>();
515     auto subscriptionClient = getClient()->getSubscriptionClient(callback);
516     auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
517 
518     ASSERT_TRUE(result.ok());
519     ASSERT_EQ(getVhal()->getUnsubscribedPropId(), TEST_PROP_ID);
520 }
521 
TEST_F(HidlVhalClientTest,testUnubscribeError)522 TEST_F(HidlVhalClientTest, testUnubscribeError) {
523     getVhal()->setStatus(StatusCode::INTERNAL_ERROR);
524     auto callback = std::make_shared<MockSubscriptionCallback>();
525     auto subscriptionClient = getClient()->getSubscriptionClient(callback);
526     auto result = subscriptionClient->unsubscribe({TEST_PROP_ID});
527 
528     ASSERT_FALSE(result.ok());
529 }
530 
TEST_F(HidlVhalClientTest,testGetRemoteInterfaceVersion)531 TEST_F(HidlVhalClientTest, testGetRemoteInterfaceVersion) {
532     // getRemoteInterfaceVersion will always return 0 for HIDL client.
533     ASSERT_EQ(getClient()->getRemoteInterfaceVersion(), 0);
534 }
535 
TEST_F(HidlVhalClientTest,testHidlHalPropValueClone_valueIsTheSame)536 TEST_F(HidlVhalClientTest, testHidlHalPropValueClone_valueIsTheSame) {
537     VehiclePropValue testProp{.prop = TEST_PROP_ID,
538                               .areaId = TEST_AREA_ID,
539                               .value = {
540                                       .int32Values = {1, 2},
541                                       .floatValues = {1.1, 2.2},
542                               }};
543     auto testPropCopy = testProp;
544     std::unique_ptr<IHalPropValue> halPropValue =
545             std::make_unique<HidlHalPropValue>(std::move(testPropCopy));
546     auto halPropValueClone = halPropValue->clone();
547 
548     EXPECT_EQ(halPropValueClone->getPropId(), TEST_PROP_ID);
549     EXPECT_EQ(halPropValueClone->getAreaId(), TEST_AREA_ID);
550     EXPECT_EQ(halPropValueClone->getInt32Values(), std::vector<int32_t>({1, 2}));
551     EXPECT_EQ(halPropValueClone->getFloatValues(), std::vector<float>({1.1, 2.2}));
552 }
553 
TEST_F(HidlVhalClientTest,testHidlHalPropValueClone_modifyCloneDoesNotAffectOrig)554 TEST_F(HidlVhalClientTest, testHidlHalPropValueClone_modifyCloneDoesNotAffectOrig) {
555     std::vector<int32_t> int32Values1 = {1, 2};
556     std::vector<float> floatValues1 = {1.1, 2.2};
557     std::vector<int32_t> int32Values2 = {5, 4, 3, 2, 1};
558     std::vector<float> floatValues2 = {3.3, 2.2, 1.1};
559 
560     VehiclePropValue testProp{.prop = TEST_PROP_ID,
561                               .areaId = TEST_AREA_ID,
562                               .value = {
563                                       .int32Values = int32Values1,
564                                       .floatValues = floatValues1,
565                               }};
566     auto testPropCopy = testProp;
567     std::unique_ptr<IHalPropValue> halPropValue =
568             std::make_unique<HidlHalPropValue>(std::move(testPropCopy));
569     auto halPropValueClone = halPropValue->clone();
570 
571     halPropValueClone->setInt32Values(int32Values2);
572     halPropValueClone->setFloatValues(floatValues2);
573 
574     EXPECT_EQ(halPropValue->getInt32Values(), int32Values1);
575     EXPECT_EQ(halPropValue->getFloatValues(), floatValues1);
576     EXPECT_EQ(halPropValueClone->getInt32Values(), int32Values2);
577     EXPECT_EQ(halPropValueClone->getFloatValues(), floatValues2);
578 }
579 
580 }  // namespace hidl_test
581 }  // namespace vhal
582 }  // namespace automotive
583 }  // namespace frameworks
584 }  // namespace android
585