xref: /aosp_15_r20/hardware/interfaces/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /******************************************************************************
2  *
3  * Copyright (C) 2021 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include "VehicleManager_fuzzer.h"
22 #include <utils/SystemClock.h>
23 #include <vhal_v2_0/Obd2SensorStore.h>
24 #include <vhal_v2_0/WatchdogClient.h>
25 
26 namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
27 
28 using ::aidl::android::automotive::watchdog::TimeoutLength;
29 using ::android::elapsedRealtimeNano;
30 using ::android::Looper;
31 using ::android::sp;
32 using ::android::hardware::hidl_handle;
33 using ::android::hardware::hidl_string;
34 using ::android::hardware::hidl_vec;
35 using ::android::hardware::automotive::vehicle::V2_0::DiagnosticFloatSensorIndex;
36 using ::android::hardware::automotive::vehicle::V2_0::DiagnosticIntegerSensorIndex;
37 using ::android::hardware::automotive::vehicle::V2_0::kCustomComplexProperty;
38 using ::android::hardware::automotive::vehicle::V2_0::kVehicleProperties;
39 using ::android::hardware::automotive::vehicle::V2_0::MockedVehicleCallback;
40 using ::android::hardware::automotive::vehicle::V2_0::Obd2SensorStore;
41 using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
42 using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
43 using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
44 using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
45 using ::android::hardware::automotive::vehicle::V2_0::VehicleAreaConfig;
46 using ::android::hardware::automotive::vehicle::V2_0::VehicleHal;
47 using ::android::hardware::automotive::vehicle::V2_0::VehicleHalManager;
48 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
49 using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
50 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyAccess;
51 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyChangeMode;
52 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
53 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyType;
54 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
55 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
56 using ::android::hardware::automotive::vehicle::V2_0::VmsMessageType;
57 using ::android::hardware::automotive::vehicle::V2_0::WatchdogClient;
58 using ::android::hardware::automotive::vehicle::V2_0::vms::createAvailabilityRequest;
59 using ::android::hardware::automotive::vehicle::V2_0::vms::createBaseVmsMessage;
60 using ::android::hardware::automotive::vehicle::V2_0::vms::createPublisherIdRequest;
61 using ::android::hardware::automotive::vehicle::V2_0::vms::createStartSessionMessage;
62 using ::android::hardware::automotive::vehicle::V2_0::vms::createSubscriptionsRequest;
63 using ::android::hardware::automotive::vehicle::V2_0::vms::getAvailableLayers;
64 using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForAvailabilityState;
65 using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForSubscriptionsState;
66 using ::android::hardware::automotive::vehicle::V2_0::vms::hasServiceNewlyStarted;
67 using ::android::hardware::automotive::vehicle::V2_0::vms::isAvailabilitySequenceNumberNewer;
68 using ::android::hardware::automotive::vehicle::V2_0::vms::isSequenceNumberNewer;
69 using ::android::hardware::automotive::vehicle::V2_0::vms::isValidVmsMessage;
70 using ::android::hardware::automotive::vehicle::V2_0::vms::parseData;
71 using ::android::hardware::automotive::vehicle::V2_0::vms::parseMessageType;
72 using ::android::hardware::automotive::vehicle::V2_0::vms::parsePublisherIdResponse;
73 using ::android::hardware::automotive::vehicle::V2_0::vms::parseStartSessionMessage;
74 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayer;
75 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerAndPublisher;
76 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
77 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
78 
79 std::string kCarMake;
80 constexpr int32_t kMaxCaseMessage = 8;
81 constexpr int32_t kMaxRuns = 20;
82 constexpr int32_t kMaxSize = 1000;
83 constexpr int32_t kMinSize = 0;
84 constexpr int32_t kMaxFileSize = 100;
85 float kFloatValue;
86 std::vector<int32_t> kVec32;
87 std::vector<int64_t> kVec64;
88 std::vector<uint8_t> kVec8;
89 std::vector<float> kVecFloat;
90 static const std::vector<std::string> kSampleDtcs = {"P0070",
91                                                      "P0102"
92                                                      "P0123"};
93 
get(const VehiclePropValue & requestedPropValue,StatusCode * outStatus)94 MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
95         const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
96     VehiclePropValuePtr pValue = nullptr;
97     if (outStatus == nullptr) {
98         return pValue;
99     }
100     auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
101     int32_t areaId = requestedPropValue.areaId;
102     *outStatus = StatusCode::OK;
103 
104     switch (property) {
105         case VehicleProperty::INFO_MAKE:
106             pValue = getValuePool()->obtainString(kCarMake.c_str());
107             break;
108         case VehicleProperty::INFO_FUEL_CAPACITY:
109             if (mFuelCapacityAttemptsLeft-- > 0) {
110                 *outStatus = StatusCode::TRY_AGAIN;
111             } else {
112                 pValue = getValuePool()->obtainFloat(kFloatValue);
113             }
114             break;
115         default:
116             if (requestedPropValue.prop == kCustomComplexProperty) {
117                 pValue = getValuePool()->obtainComplex();
118                 pValue->value.int32Values = hidl_vec<int32_t>{kVec32};
119                 pValue->value.int64Values = hidl_vec<int64_t>{kVec64};
120                 pValue->value.floatValues = hidl_vec<float_t>{kVecFloat};
121                 pValue->value.bytes = hidl_vec<uint8_t>{kVec8};
122                 pValue->value.stringValue = kCarMake.c_str();
123                 break;
124             }
125             auto key = makeKey(toInt(property), areaId);
126             pValue = getValuePool()->obtain(mValues[key]);
127     }
128 
129     if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
130         pValue->prop = toInt(property);
131         pValue->areaId = areaId;
132         pValue->timestamp = elapsedRealtimeNano();
133     }
134 
135     return pValue;
136 }
137 
initValue()138 void VehicleHalManagerFuzzer::initValue() {
139     kCarMake = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
140     kFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
141     fillParameter<int32_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
142                            kVec32);
143     fillParameter<int64_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
144                            kVec64);
145     fillParameter<uint8_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
146                            kVec8);
147     size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
148     for (size_t i = 0; i < size; ++i) {
149         kVecFloat.push_back(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
150     }
151 }
152 
process(const uint8_t * data,size_t size)153 void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
154     mFuzzedDataProvider = new FuzzedDataProvider(data, size);
155     initValue();
156     /* Limited while loop runs to prevent timeouts caused
157      * by repeated calls to high-execution-time APIs.
158      */
159     size_t maxRuns = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxRuns);
160     size_t itr = 0;
161     while (mFuzzedDataProvider->remaining_bytes() && ++itr <= maxRuns) {
162         auto invokeVehicleHalManagerFuzzer =
163                 mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
164                         [&]() { invokeDebug(); },
165                         [&]() { invokePropConfigs(); },
166                         [&]() { invokeSubscribe(); },
167                         [&]() { invokeSetAndGetValues(); },
168                         [&]() { invokeObd2SensorStore(); },
169                         [&]() { invokeVmsUtils(); },
170                         [&]() { invokeVehiclePropStore(); },
171                         [&]() { invokeWatchDogClient(); },
172                 });
173         invokeVehicleHalManagerFuzzer();
174     }
175 }
176 
invokeDebug()177 void VehicleHalManagerFuzzer::invokeDebug() {
178     hidl_handle fd = {};
179 
180     native_handle_t* rawHandle = native_handle_create(/*numFds=*/1, /*numInts=*/0);
181     fd.setTo(native_handle_clone(rawHandle), /*shouldOwn=*/true);
182     int32_t size = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxFileSize);
183     hidl_vec<hidl_string> options(size);
184 
185     for (int32_t idx = 0; idx < size; ++idx) {
186         if (idx == 0 && mFuzzedDataProvider->ConsumeBool()) {
187             options[idx] = mFuzzedDataProvider->PickValueInArray(
188                     {"--help", "--list", "--get", "--set", "", "invalid"});
189         } else if (idx == 2 && mFuzzedDataProvider->ConsumeBool()) {
190             options[idx] =
191                     mFuzzedDataProvider->PickValueInArray({"-i", "-i64", "-f", "-s", "-b", "-a"});
192         } else if (mFuzzedDataProvider->ConsumeBool()) {
193             options[idx] = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxSize);
194         } else {
195             options[idx] = std::to_string(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
196         }
197     }
198 
199     if (mFuzzedDataProvider->ConsumeBool()) {
200         mManager->debug(fd, {});
201     } else {
202         mManager->debug(fd, options);
203     }
204     native_handle_delete(rawHandle);
205 }
206 
invokePropConfigs()207 void VehicleHalManagerFuzzer::invokePropConfigs() {
208     int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
209     int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
210 
211     hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
212     auto invokePropConfigsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
213             [&]() {
214                 mManager->getPropConfigs(
215                         properties, []([[maybe_unused]] StatusCode status,
216                                        [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
217             },
218             [&]() {
219                 mManager->getPropConfigs(
220                         {mFuzzedDataProvider->ConsumeIntegral<int32_t>()},
221                         []([[maybe_unused]] StatusCode status,
222                            [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
223             },
224             [&]() {
225                 mManager->getAllPropConfigs(
226                         []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
227             },
228 
229     });
230     invokePropConfigsAPI();
231 }
232 
invokeSubscribe()233 void VehicleHalManagerFuzzer::invokeSubscribe() {
234     int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
235     int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
236 
237     sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
238     VehiclePropertyType type =
239             static_cast<VehiclePropertyType>(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
240 
241     auto invokeSubscribeAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
242             [&]() {
243                 size_t size =
244                         mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
245                 hidl_vec<SubscribeOptions> options(size);
246                 for (size_t idx = 0; idx < size; ++idx) {
247                     options[idx] = {SubscribeOptions{
248                             .propId = mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
249                             .flags = static_cast<SubscribeFlags>(
250                                     mFuzzedDataProvider->ConsumeIntegral<int32_t>())}};
251                 }
252                 mManager->subscribe(cb, options);
253             },
254             [&]() {
255                 auto unsubscribedValue = mObjectPool->obtain(type);
256                 if (!unsubscribedValue) {
257                     return;
258                 }
259                 unsubscribedValue->prop = vehicleProp2;
260                 unsubscribedValue->value.int32Values[0] = INT32_MAX;
261                 mHal->sendPropEvent(std::move(unsubscribedValue));
262                 cb->waitForExpectedEvents(mFuzzedDataProvider->ConsumeIntegral<size_t>());
263             },
264             [&]() {
265                 const auto prop1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
266                 mManager->unsubscribe(cb, prop1);
267             },
268             [&]() {
269                 mHal->sendHalError(StatusCode::TRY_AGAIN, vehicleProp3,
270                                    mFuzzedDataProvider->ConsumeIntegral<int32_t>() /*areaId=*/);
271             },
272 
273     });
274     invokeSubscribeAPI();
275 }
276 
invokeSetAndGetValues()277 void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
278     auto invokeSetAndGetAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
279             [&]() {
280                 invokeGet(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
281                           mFuzzedDataProvider->ConsumeIntegral<int32_t>());
282             },
283             [&]() { mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>()); },
284             [&]() { mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>()); },
285             [&]() { mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool()); },
286             [&]() {
287                 int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
288                 auto expectedValue =
289                         mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
290                 expectedValue->prop = vehicleProp2;
291                 expectedValue->areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
292                 mManager->set(*expectedValue.get());
293             },
294     });
295     invokeSetAndGetAPI();
296 }
297 
invokeObd2SensorStore()298 void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
299     size_t diagnosticInt = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
300     size_t diagnosticFloat =
301             mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
302 
303     std::unique_ptr<Obd2SensorStore> sensorStore(
304             new Obd2SensorStore(diagnosticInt, diagnosticFloat));
305 
306     if (!sensorStore.get()) {
307         return;
308     }
309 
310     auto invokeObd2SensorStoreAPI =
311             mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
312                     [&]() {
313                         int32_t diagnosticIntValue =
314                                 mFuzzedDataProvider->ConsumeIntegral<int32_t>();
315                         int32_t diagnosticIntIndex =
316                                 mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
317                                         kMinSize,
318                                         toInt(DiagnosticIntegerSensorIndex::LAST_SYSTEM_INDEX) +
319                                                 diagnosticInt);
320                         sensorStore->setIntegerSensor(
321                                 static_cast<DiagnosticIntegerSensorIndex>(diagnosticIntIndex),
322                                 diagnosticIntValue);
323                     },
324                     [&]() {
325                         float diagnosticFloatValue =
326                                 mFuzzedDataProvider->ConsumeFloatingPoint<float>();
327                         int32_t diagnosticFloatIndex =
328                                 mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
329                                         kMinSize,
330                                         toInt(DiagnosticFloatSensorIndex::LAST_SYSTEM_INDEX) +
331                                                 diagnosticFloat);
332                         sensorStore->setFloatSensor(
333                                 static_cast<DiagnosticFloatSensorIndex>(diagnosticFloatIndex),
334                                 diagnosticFloatValue);
335                     },
336                     [&]() { sensorStore->getIntegerSensors(); },
337                     [&]() { sensorStore->getFloatSensors(); },
338                     [&]() { sensorStore->getSensorsBitmask(); },
339                     [&]() {
340                         for (auto&& dtc : kSampleDtcs) {
341                             VehiclePropertyType type = static_cast<VehiclePropertyType>(
342                                     mFuzzedDataProvider->ConsumeIntegral<int32_t>());
343                             auto freezeFrame = createVehiclePropValue(
344                                     type, mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
345                                                   kMinSize, kMaxSize));
346                             if (!freezeFrame.get()) {
347                                 return;
348                             }
349                             freezeFrame->prop = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
350                             sensorStore->fillPropValue(dtc, freezeFrame.get());
351                         }
352                     },
353             });
354     invokeObd2SensorStoreAPI();
355 }
356 
invokeVmsUtils()357 void VehicleHalManagerFuzzer::invokeVmsUtils() {
358     std::unique_ptr<VehiclePropValue> message;
359     int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
360     VmsLayer layer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
361                    mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
362                    mFuzzedDataProvider->ConsumeIntegral<int32_t>());
363     VmsOffers offers = {
364             intValue,
365             {VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
366                                        mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
367                                        mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
368     const VmsLayerAndPublisher layer_and_publisher(
369             VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
370                      mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
371                      mFuzzedDataProvider->ConsumeIntegral<int32_t>()),
372             intValue);
373 
374     switch (mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxCaseMessage)) {
375         case 0: {
376             message = createSubscribeMessage(layer);
377             break;
378         }
379         case 1: {
380             message = createUnsubscribeMessage(layer);
381             break;
382         }
383         case 2: {
384             message = createSubscriptionsRequest();
385             break;
386         }
387         case 3: {
388             message = createOfferingMessage(offers);
389             break;
390         }
391         case 4: {
392             message = createAvailabilityRequest();
393             break;
394         }
395         case 5: {
396             std::string pub_bytes;
397             if (mFuzzedDataProvider->ConsumeBool()) {
398                 pub_bytes = "pub_id";
399             } else {
400                 pub_bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
401             }
402             message = createPublisherIdRequest(pub_bytes);
403             break;
404         }
405         case 6: {
406             std::string bytes = "placeholder";
407             if (mFuzzedDataProvider->ConsumeBool()) {
408                 bytes = "placeholder";
409             } else {
410                 bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
411             }
412             message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
413             break;
414         }
415         case 7: {
416             message = createBaseVmsMessage(
417                     mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
418             break;
419         }
420         case 8: {
421             message = createStartSessionMessage(intValue, intValue + 1);
422             break;
423         }
424     }
425 
426     isValidVmsMessage(*message);
427     message->value.int32Values =
428             hidl_vec<int32_t>{mFuzzedDataProvider->ConsumeIntegral<int32_t>(), intValue};
429 
430     auto invokeVmsUtilsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
431             [&]() { parseData(*message); },
432             [&]() { createSubscribeToPublisherMessage(layer_and_publisher); },
433             [&]() { createUnsubscribeToPublisherMessage(layer_and_publisher); },
434             [&]() { parsePublisherIdResponse(*message); },
435             [&]() { getSequenceNumberForSubscriptionsState(*message); },
436             [&]() { isSequenceNumberNewer(*message, intValue + 1); },
437             [&]() {
438                 invokeGetSubscribedLayers(
439                         (VmsMessageType)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
440             },
441             [&]() { hasServiceNewlyStarted(*message); },
442             [&]() { parseMessageType(*message); },
443             [&]() { isAvailabilitySequenceNumberNewer(*message, intValue + 1); },
444             [&]() { getSequenceNumberForAvailabilityState(*message); },
445             [&]() {
446                 int32_t new_service_id;
447                 parseStartSessionMessage(*message, -1, 0, &new_service_id);
448             },
449     });
450     invokeVmsUtilsAPI();
451 }
452 
invokeGet(int32_t property,int32_t areaId)453 void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
454     VehiclePropValue requestedValue{};
455     requestedValue.prop = property;
456     requestedValue.areaId = areaId;
457     mActualValue = VehiclePropValue{};  // reset previous values
458 
459     StatusCode refStatus;
460     VehiclePropValue refValue;
461     mManager->get(requestedValue,
462                   [&refStatus, &refValue](StatusCode status, const VehiclePropValue& value) {
463                       refStatus = status;
464                       refValue = value;
465                   });
466 
467     mActualValue = refValue;
468     mActualStatusCode = refStatus;
469 }
470 
invokeGetSubscribedLayers(VmsMessageType)471 void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType /*type*/) {
472     int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
473     VmsOffers offers = {
474             intValue,
475             {VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
476                                        mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
477                                        mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
478     auto message = createBaseVmsMessage(
479             mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxFileSize));
480     std::vector<int32_t> v;
481     size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
482     for (size_t i = 0; i < size; i++) {
483         v.push_back(mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
484     }
485 
486     message->value.int32Values = hidl_vec<int32_t>(v);
487     if (!isValidVmsMessage(*message)) {
488         return;
489     }
490 
491     if (mFuzzedDataProvider->ConsumeBool()) {
492         getSubscribedLayers(*message, offers);
493     } else {
494         getAvailableLayers(*message);
495     }
496 }
497 
invokeVehiclePropStore()498 void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
499     bool shouldWriteStatus = mFuzzedDataProvider->ConsumeBool();
500     int32_t vehicleProp = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
501     auto store = std::make_unique<VehiclePropertyStore>();
502     VehiclePropConfig config{
503             .prop = vehicleProp,
504             .access = VehiclePropertyAccess::READ,
505             .changeMode = VehiclePropertyChangeMode::STATIC,
506             .areaConfigs = {VehicleAreaConfig{
507                     .areaId = (mFuzzedDataProvider->ConsumeIntegral<int32_t>())}},
508     };
509     VehiclePropValue propValue{};
510     propValue.prop = vehicleProp;
511     propValue.areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
512 
513     auto invokeVehiclePropStoreAPI =
514             mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
515                     [&]() { store->registerProperty(config); },
516                     [&]() { store->writeValue(propValue, shouldWriteStatus); },
517                     [&]() { store->readAllValues(); },
518                     [&]() { store->getAllConfigs(); },
519                     [&]() { store->getConfigOrNull(vehicleProp); },
520                     [&]() { store->readValuesForProperty(vehicleProp); },
521                     [&]() { store->readValueOrNull(propValue); },
522                     [&]() {
523                         store->readValueOrNull(propValue.prop, propValue.areaId,
524                                                mFuzzedDataProvider->ConsumeIntegralInRange<int64_t>(
525                                                        kMinSize, kMaxFileSize));
526                     },
527                     [&]() { store->removeValuesForProperty(vehicleProp); },
528                     [&]() { store->removeValue(propValue); },
529                     [&]() {
530                         if (store->getConfigOrNull(vehicleProp)) {
531                             store->getConfigOrDie(vehicleProp);
532                         }
533                     },
534             });
535     invokeVehiclePropStoreAPI();
536 }
537 
invokeWatchDogClient()538 void VehicleHalManagerFuzzer::invokeWatchDogClient() {
539     sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
540     if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, mManager.get());
541         watchdogClient->initialize()) {
542         if (mFuzzedDataProvider->ConsumeBool()) {
543             watchdogClient->checkIfAlive(
544                     mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
545                     (TimeoutLength)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
546         }
547         watchdogClient->prepareProcessTermination();
548     }
549 }
550 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)551 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
552     VehicleHalManagerFuzzer vmFuzzer;
553     vmFuzzer.process(data, size);
554     return 0;
555 }
556 
557 }  // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
558