• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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