Migrate fake value generator.

Test: atest FakeVehicleHalValueGeneratorsTest
Bug: 201830716
Change-Id: Ic113c9b189a07140a288d6d03d3a8a2b9061881f
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index c5702aa..9924581 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -11,6 +11,9 @@
     },
     {
       "name": "FakeVehicleHardwareTest"
+    },
+    {
+      "name": "FakeVehicleHalValueGeneratorsTest"
     }
   ]
 }
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
new file mode 100644
index 0000000..8116ed2
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_JsonFakeValueGenerator_H_
+#define android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_JsonFakeValueGenerator_H_
+
+#include "FakeValueGenerator.h"
+
+#include <json/json.h>
+
+#include <iostream>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace fake {
+
+class JsonFakeValueGenerator : public FakeValueGenerator {
+  public:
+    // Create a new JSON fake value generator. {@code request.value.stringValue} is the JSON file
+    // name. {@code request.value.int32Values[1]} if exists, is the number of iterations. If
+    // {@code int32Values} has less than 2 elements, number of iterations would be set to -1, which
+    // means iterate indefinitely.
+    explicit JsonFakeValueGenerator(
+            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& request);
+    // Create a new JSON fake value generator using the specified JSON file path. All the events
+    // in the JSON file would be generated for number of {@code iteration}. If iteration is 0, no
+    // value would be generated. If iteration is less than 0, it would iterate indefinitely.
+    explicit JsonFakeValueGenerator(const std::string& path, int32_t iteration);
+    // Create a new JSON fake value generator using the specified JSON file path. All the events
+    // in the JSON file would be generated once.
+    explicit JsonFakeValueGenerator(const std::string& path);
+
+    ~JsonFakeValueGenerator() = default;
+
+    std::optional<::aidl::android::hardware::automotive::vehicle::VehiclePropValue> nextEvent()
+            override;
+    const std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
+    getAllEvents();
+
+  private:
+    size_t mEventIndex = 0;
+    std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue> mEvents;
+    long mLastEventTimestamp = 0;
+    int32_t mNumOfIterations = 0;
+
+    void setBit(std::vector<uint8_t>& bytes, size_t idx);
+    void init(const std::string& path, int32_t iteration);
+};
+
+}  // namespace fake
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_JsonFakeValueGenerator_H_
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
new file mode 100644
index 0000000..bd004f3
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_LinearFakeValueGenerator_H_
+#define android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_LinearFakeValueGenerator_H_
+
+#include "FakeValueGenerator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace fake {
+
+class LinearFakeValueGenerator : public FakeValueGenerator {
+  public:
+    // A linear value generator initialized using values in request.
+    // int32Values[1]: propId
+    // floatValues[0]: middleValue and currentValue
+    // floatValues[1]: dispersion
+    // floatValues[2]: increment
+    // int64Values[0]: interval
+    // {@code propId} must be INT32 or INT64 or FLOAT type.
+    explicit LinearFakeValueGenerator(
+            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& request);
+    // A linear value generator in range [middleValue - dispersion, middleValue + dispersion),
+    // starts at 'currentValue' and at each 'interval', increase by 'increment' and loop back if
+    // exceeds middleValue + dispersion. {@code propId} must be INT32 or INT64 or FLOAT type.
+    explicit LinearFakeValueGenerator(int32_t propId, float middleValue, float initValue,
+                                      float dispersion, float increment, int64_t interval);
+    ~LinearFakeValueGenerator() = default;
+
+    std::optional<::aidl::android::hardware::automotive::vehicle::VehiclePropValue> nextEvent()
+            override;
+
+  private:
+    // In every timer tick we may want to generate new value based on initial value for debug
+    // purpose. It's better to have sequential values to see if events gets delivered in order
+    // to the client.
+    struct GeneratorCfg {
+        int32_t propId;
+        float middleValue;
+        float currentValue;  //  Should be in range (middleValue +/- dispersion).
+        float dispersion;    //  Defines minimum and maximum value based on initial value.
+        float increment;     //  Value that we will be added to currentValue with each timer tick.
+        int64_t interval;
+        long lastEventTimestamp;
+    };
+
+    GeneratorCfg mGenCfg;
+
+    void initGenCfg(int32_t propId, float middleValue, float initValue, float dispersion,
+                    float increment, int64_t interval);
+};
+
+}  // namespace fake
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_fake_impl_GeneratorHub_include_LinearFakeValueGenerator_H_
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
new file mode 100644
index 0000000..521ce45
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "JsonFakeValueGenerator"
+
+#include "JsonFakeValueGenerator.h"
+
+#include <fstream>
+#include <type_traits>
+#include <typeinfo>
+
+#include <VehicleUtils.h>
+#include <android/binder_enums.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace fake {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::DiagnosticFloatSensorIndex;
+using ::aidl::android::hardware::automotive::vehicle::DiagnosticIntegerSensorIndex;
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+template <class T>
+int getLastIndex() {
+    auto range = ::ndk::enum_range<T>();
+    auto it = range.begin();
+    while (std::next(it) != range.end()) {
+        it++;
+    }
+    return toInt(*it);
+}
+
+bool isDiagnosticProperty(int32_t prop) {
+    return prop == toInt(VehicleProperty::OBD2_LIVE_FRAME) ||
+           prop == toInt(VehicleProperty::OBD2_FREEZE_FRAME);
+}
+
+void setBit(std::vector<uint8_t>& bytes, size_t idx) {
+    uint8_t mask = 1 << (idx % 8);
+    bytes[idx / 8] |= mask;
+}
+
+template <typename T>
+void copyJsonArray(const Json::Value& jsonArray, std::vector<T>& dest) {
+    dest.resize(jsonArray.size());
+    for (Json::Value::ArrayIndex i = 0; i < jsonArray.size(); i++) {
+        if (std::is_same<T, int32_t>::value) {
+            dest[i] = jsonArray[i].asInt();
+        } else if (std::is_same<T, int64_t>::value) {
+            dest[i] = jsonArray[i].asInt64();
+        } else if (std::is_same<T, float>::value) {
+            dest[i] = jsonArray[i].asFloat();
+        }
+    }
+}
+
+void copyMixedValueJson(const Json::Value& jsonValue, RawPropValues& dest) {
+    copyJsonArray(jsonValue["int32Values"], dest.int32Values);
+    copyJsonArray(jsonValue["int64Values"], dest.int64Values);
+    copyJsonArray(jsonValue["floatValues"], dest.floatValues);
+    dest.stringValue = jsonValue["stringValue"].asString();
+}
+
+std::vector<uint8_t> generateDiagnosticBytes(const RawPropValues& diagnosticValue) {
+    size_t lastIntegerSensorIndex =
+            static_cast<size_t>(getLastIndex<DiagnosticIntegerSensorIndex>());
+    size_t lastFloatSensorIndex = static_cast<size_t>(getLastIndex<DiagnosticFloatSensorIndex>());
+
+    size_t byteSize = (lastIntegerSensorIndex + lastFloatSensorIndex + 2);
+    std::vector<uint8_t> bytes((byteSize + 7) / 8);
+
+    auto& int32Values = diagnosticValue.int32Values;
+    for (size_t i = 0; i < int32Values.size(); i++) {
+        if (int32Values[i] != 0) {
+            setBit(bytes, i);
+        }
+    }
+
+    auto& floatValues = diagnosticValue.floatValues;
+    for (size_t i = 0; i < floatValues.size(); i++) {
+        if (floatValues[i] != 0.0) {
+            setBit(bytes, i + lastIntegerSensorIndex + 1);
+        }
+    }
+    return bytes;
+}
+
+std::vector<VehiclePropValue> parseFakeValueJson(std::istream& is) {
+    std::vector<VehiclePropValue> fakeVhalEvents;
+
+    Json::CharReaderBuilder builder;
+    Json::Value rawEvents;
+    std::string errorMessage;
+    if (!Json::parseFromStream(builder, is, &rawEvents, &errorMessage)) {
+        ALOGE("%s: Failed to parse fake data JSON file. Error: %s", __func__, errorMessage.c_str());
+        return fakeVhalEvents;
+    }
+
+    for (Json::Value::ArrayIndex i = 0; i < rawEvents.size(); i++) {
+        Json::Value rawEvent = rawEvents[i];
+        if (!rawEvent.isObject()) {
+            ALOGE("%s: VHAL JSON event should be an object, %s", __func__,
+                  rawEvent.toStyledString().c_str());
+            continue;
+        }
+        if (rawEvent["prop"].empty() || rawEvent["areaId"].empty() || rawEvent["value"].empty() ||
+            rawEvent["timestamp"].empty()) {
+            ALOGE("%s: VHAL JSON event has missing fields, skip it, %s", __func__,
+                  rawEvent.toStyledString().c_str());
+            continue;
+        }
+        VehiclePropValue event = {
+                .timestamp = rawEvent["timestamp"].asInt64(),
+                .areaId = rawEvent["areaId"].asInt(),
+                .prop = rawEvent["prop"].asInt(),
+        };
+
+        Json::Value rawEventValue = rawEvent["value"];
+        auto& value = event.value;
+        int32_t count;
+        switch (getPropType(event.prop)) {
+            case VehiclePropertyType::BOOLEAN:
+            case VehiclePropertyType::INT32:
+                value.int32Values.resize(1);
+                value.int32Values[0] = rawEventValue.asInt();
+                break;
+            case VehiclePropertyType::INT64:
+                value.int64Values.resize(1);
+                value.int64Values[0] = rawEventValue.asInt64();
+                break;
+            case VehiclePropertyType::FLOAT:
+                value.floatValues.resize(1);
+                value.floatValues[0] = rawEventValue.asFloat();
+                break;
+            case VehiclePropertyType::STRING:
+                value.stringValue = rawEventValue.asString();
+                break;
+            case VehiclePropertyType::INT32_VEC:
+                value.int32Values.resize(rawEventValue.size());
+                count = 0;
+                for (auto& it : rawEventValue) {
+                    value.int32Values[count++] = it.asInt();
+                }
+                break;
+            case VehiclePropertyType::MIXED:
+                copyMixedValueJson(rawEventValue, value);
+                if (isDiagnosticProperty(event.prop)) {
+                    value.byteValues = generateDiagnosticBytes(value);
+                }
+                break;
+            default:
+                ALOGE("%s: unsupported type for property: 0x%x", __func__, event.prop);
+                continue;
+        }
+        fakeVhalEvents.push_back(event);
+    }
+    return fakeVhalEvents;
+}
+
+}  // namespace
+
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path) {
+    init(path, 1);
+}
+
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path, int32_t iteration) {
+    init(path, iteration);
+}
+
+JsonFakeValueGenerator::JsonFakeValueGenerator(const VehiclePropValue& request) {
+    const auto& v = request.value;
+    // Iterate infinitely if iteration number is not provided
+    int32_t numOfIterations = v.int32Values.size() < 2 ? -1 : v.int32Values[1];
+
+    init(v.stringValue, numOfIterations);
+}
+
+void JsonFakeValueGenerator::init(const std::string& path, int32_t iteration) {
+    std::ifstream ifs(path);
+    if (!ifs) {
+        ALOGE("%s: couldn't open %s for parsing.", __func__, path.c_str());
+        return;
+    }
+    mEvents = parseFakeValueJson(ifs);
+    mNumOfIterations = iteration;
+}
+
+const std::vector<VehiclePropValue>& JsonFakeValueGenerator::getAllEvents() {
+    return mEvents;
+}
+
+std::optional<VehiclePropValue> JsonFakeValueGenerator::nextEvent() {
+    if (mNumOfIterations == 0 || mEvents.size() == 0) {
+        return std::nullopt;
+    }
+
+    VehiclePropValue generatedValue = mEvents[mEventIndex];
+
+    if (mLastEventTimestamp == 0) {
+        mLastEventTimestamp = elapsedRealtimeNano();
+    } else {
+        long nextEventTime = 0;
+        if (mEventIndex > 0) {
+            // All events (start from 2nd one) are supposed to happen in the future with a delay
+            // equals to the duration between previous and current event.
+            nextEventTime = mLastEventTimestamp +
+                            (mEvents[mEventIndex].timestamp - mEvents[mEventIndex - 1].timestamp);
+        } else {
+            // We are starting another iteration, immediately send the next event after 1ms.
+            nextEventTime = mLastEventTimestamp + 1000000;
+        }
+        // Prevent overflow.
+        assert(nextEventTime > mLastEventTimestamp);
+        mLastEventTimestamp = nextEventTime;
+    }
+
+    mEventIndex++;
+    if (mEventIndex == mEvents.size()) {
+        mEventIndex = 0;
+        if (mNumOfIterations > 0) {
+            mNumOfIterations--;
+        }
+    }
+
+    generatedValue.timestamp = mLastEventTimestamp;
+
+    return generatedValue;
+}
+
+}  // namespace fake
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
new file mode 100644
index 0000000..9133144
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LinearFakeValueGenerator"
+
+#include "LinearFakeValueGenerator.h"
+
+#include <VehicleUtils.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace fake {
+
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+LinearFakeValueGenerator::LinearFakeValueGenerator(int32_t propId, float middleValue,
+                                                   float initValue, float dispersion,
+                                                   float increment, int64_t interval) {
+    initGenCfg(propId, middleValue, initValue, dispersion, increment, interval);
+}
+
+LinearFakeValueGenerator::LinearFakeValueGenerator(const VehiclePropValue& request) {
+    const auto& v = request.value;
+    initGenCfg(v.int32Values[1], v.floatValues[0], v.floatValues[0], v.floatValues[1],
+               v.floatValues[2], v.int64Values[0]);
+}
+
+void LinearFakeValueGenerator::initGenCfg(int32_t propId, float middleValue, float initValue,
+                                          float dispersion, float increment, int64_t interval) {
+    // Other types are not supported.
+    assert(getPropType(propId) == VehicleProperty::INT32 ||
+           getPropType(propId) == VehicleProperty::INT64 ||
+           getPropType(propId) == VehicleProperty::FLOAT);
+
+    if (initValue < middleValue - dispersion || initValue >= middleValue + dispersion) {
+        ALOGW("%s: invalid initValue: %f, out of range, default to %f", __func__, initValue,
+              middleValue);
+        initValue = middleValue;
+    }
+    mGenCfg = GeneratorCfg{
+            .propId = propId,
+            .middleValue = middleValue,
+            .currentValue = initValue,
+            .dispersion = dispersion,
+            .increment = increment,
+            .interval = interval,
+    };
+}
+
+std::optional<VehiclePropValue> LinearFakeValueGenerator::nextEvent() {
+    VehiclePropValue event = {
+            .prop = mGenCfg.propId,
+    };
+    auto& value = event.value;
+    switch (getPropType(event.prop)) {
+        case VehiclePropertyType::INT32:
+            value.int32Values = {static_cast<int32_t>(mGenCfg.currentValue)};
+            break;
+        case VehiclePropertyType::INT64:
+            value.int64Values = {static_cast<int64_t>(mGenCfg.currentValue)};
+            break;
+        case VehiclePropertyType::FLOAT:
+            value.floatValues = {mGenCfg.currentValue};
+            break;
+        default:
+            ALOGE("%s: unsupported property type for 0x%x", __func__, event.prop);
+    }
+    if (mGenCfg.lastEventTimestamp == 0) {
+        mGenCfg.lastEventTimestamp = elapsedRealtimeNano();
+    } else {
+        long nextEventTime = mGenCfg.lastEventTimestamp + mGenCfg.interval;
+        // Prevent overflow.
+        assert(nextEventTime > mGenCfg.lastEventTimestamp);
+        mGenCfg.lastEventTimestamp = nextEventTime;
+    }
+    event.timestamp = mGenCfg.lastEventTimestamp;
+
+    mGenCfg.currentValue += mGenCfg.increment;
+    if (mGenCfg.currentValue >= mGenCfg.middleValue + mGenCfg.dispersion) {
+        // Wrap around, (i - d) + c - (i + d) = c - 2 * d
+        mGenCfg.currentValue = mGenCfg.currentValue - 2 * mGenCfg.dispersion;
+    }
+    return event;
+}
+
+}  // namespace fake
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
index 981a077..d3d3a10 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
@@ -27,5 +27,19 @@
         "VehicleHalUtils",
         "FakeVehicleHalValueGenerators",
     ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    data: [
+        ":FakeVehicleHalValueGeneratorsTestFiles",
+    ],
     test_suites: ["device-tests"],
 }
+
+filegroup {
+    name: "FakeVehicleHalValueGeneratorsTestFiles",
+    srcs: [
+        "prop.json",
+        "prop_invalid.json",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
index abb3da2..929d9b3 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
@@ -15,6 +15,8 @@
  */
 
 #include <GeneratorHub.h>
+#include <JsonFakeValueGenerator.h>
+#include <LinearFakeValueGenerator.h>
 #include <VehicleUtils.h>
 #include <android-base/file.h>
 #include <android-base/thread_annotations.h>
@@ -61,6 +63,11 @@
         mHub.reset();
     }
 
+    static std::string getTestFilePath(const char* filename) {
+        static std::string baseDir = android::base::GetExecutableDirectory();
+        return baseDir + "/" + filename;
+    }
+
   private:
     void onHalEvent(const VehiclePropValue& event) {
         VehiclePropValue eventCopy = event;
@@ -138,6 +145,271 @@
             << "Must stop generating event after generator is unregistered";
 }
 
+TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorFloat) {
+    std::unique_ptr<LinearFakeValueGenerator> generator =
+            std::make_unique<LinearFakeValueGenerator>(toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+                                                       /*middleValue=*/50.0,
+                                                       /*initValue=*/30.0,
+                                                       /*dispersion=*/50.0,
+                                                       /*increment=*/20.0,
+                                                       /*interval=*/10000000);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+    int value = 30;
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
+        value = (value + 20) % 100;
+    }
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInt32) {
+    std::unique_ptr<LinearFakeValueGenerator> generator =
+            std::make_unique<LinearFakeValueGenerator>(toInt(VehicleProperty::INFO_MODEL_YEAR),
+                                                       /*middleValue=*/50.0,
+                                                       /*initValue=*/30.0,
+                                                       /*dispersion=*/50.0,
+                                                       /*increment=*/20.0,
+                                                       /*interval=*/10000000);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+    int value = 30;
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(std::vector<int32_t>({value}), events[i].value.int32Values);
+        value = (value + 20) % 100;
+    }
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInt64) {
+    std::unique_ptr<LinearFakeValueGenerator> generator =
+            std::make_unique<LinearFakeValueGenerator>(toInt(VehicleProperty::EPOCH_TIME),
+                                                       /*middleValue=*/50.0,
+                                                       /*initValue=*/30.0,
+                                                       /*dispersion=*/50.0,
+                                                       /*increment=*/20.0,
+                                                       /*interval=*/10000000);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+    int value = 30;
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(std::vector<int64_t>({value}), events[i].value.int64Values);
+        value = (value + 20) % 100;
+    }
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorUsingRequest) {
+    VehiclePropValue request;
+    request.value.int32Values = {0, toInt(VehicleProperty::PERF_VEHICLE_SPEED)};
+    request.value.floatValues = {/*middleValue=*/50.0, /*dispersion=*/50.0, /*increment=*/20.0};
+    request.value.int64Values = {/*interval=*/10000000};
+
+    std::unique_ptr<LinearFakeValueGenerator> generator =
+            std::make_unique<LinearFakeValueGenerator>(request);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+    int value = 50;
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
+        value = (value + 20) % 100;
+    }
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInvalidInitValue) {
+    std::unique_ptr<LinearFakeValueGenerator> generator =
+            std::make_unique<LinearFakeValueGenerator>(toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+                                                       /*middleValue=*/50.0,
+                                                       // Out of range
+                                                       /*initValue=*/110.0,
+                                                       /*dispersion=*/50.0,
+                                                       /*increment=*/20.0,
+                                                       /*interval=*/10000000);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+
+    // Init value would be set to middleValue if given initValue is not valid.
+    int value = 50;
+    for (size_t i = 0; i < 5; i++) {
+        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
+        value = (value + 20) % 100;
+    }
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGenerator) {
+    long currentTime = elapsedRealtimeNano();
+
+    std::unique_ptr<JsonFakeValueGenerator> generator =
+            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), 2);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    std::vector<VehiclePropValue> expectedValues = {
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {8},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {4},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {16},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {10},
+                    .prop = 289408000,
+            },
+    };
+
+    // We have two iterations.
+    for (size_t i = 0; i < 4; i++) {
+        expectedValues.push_back(expectedValues[i]);
+    }
+
+    auto events = getEvents();
+
+    long lastEventTime = currentTime;
+    for (auto& event : events) {
+        EXPECT_GT(event.timestamp, lastEventTime);
+        lastEventTime = event.timestamp;
+        event.timestamp = 0;
+    }
+
+    EXPECT_EQ(events, expectedValues);
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorIterateIndefinitely) {
+    std::unique_ptr<JsonFakeValueGenerator> generator =
+            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), -1);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = getEvents();
+
+    // Send 1 iteration takes 4ms + 1ms interval between iteration, so for 100ms we should get about
+    // 20 iteration, which is 80 events.
+    EXPECT_GT(events.size(), static_cast<size_t>(50));
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorUsingRequest) {
+    long currentTime = elapsedRealtimeNano();
+
+    VehiclePropValue request = {.value = {
+                                        .stringValue = getTestFilePath("prop.json"),
+                                        .int32Values = {0, 2},
+                                }};
+
+    std::unique_ptr<JsonFakeValueGenerator> generator =
+            std::make_unique<JsonFakeValueGenerator>(request);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    std::vector<VehiclePropValue> expectedValues = {
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {8},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {4},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {16},
+                    .prop = 289408000,
+            },
+            VehiclePropValue{
+                    .areaId = 0,
+                    .value.int32Values = {10},
+                    .prop = 289408000,
+            },
+    };
+
+    // We have two iterations.
+    for (size_t i = 0; i < 4; i++) {
+        expectedValues.push_back(expectedValues[i]);
+    }
+
+    auto events = getEvents();
+
+    long lastEventTime = currentTime;
+    for (auto& event : events) {
+        EXPECT_GT(event.timestamp, lastEventTime);
+        lastEventTime = event.timestamp;
+        event.timestamp = 0;
+    }
+
+    EXPECT_EQ(events, expectedValues);
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorInvalidFile) {
+    VehiclePropValue request = {.value = {
+                                        .stringValue = getTestFilePath("prop_invalid.json"),
+                                        .int32Values = {0, 2},
+                                }};
+
+    std::unique_ptr<JsonFakeValueGenerator> generator =
+            std::make_unique<JsonFakeValueGenerator>(request);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    ASSERT_TRUE(getEvents().empty());
+}
+
+TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorNonExistingFile) {
+    VehiclePropValue request = {.value = {
+                                        .stringValue = "non_existing_file",
+                                        .int32Values = {0, 2},
+                                }};
+
+    std::unique_ptr<JsonFakeValueGenerator> generator =
+            std::make_unique<JsonFakeValueGenerator>(request);
+    getHub()->registerGenerator(0, std::move(generator));
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    ASSERT_TRUE(getEvents().empty());
+}
+
 }  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json
new file mode 100644
index 0000000..b881109
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json
@@ -0,0 +1,26 @@
+[
+  {
+    "timestamp": 1000000,
+    "areaId": 0,
+    "value": 8,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 2000000,
+    "areaId": 0,
+    "value": 4,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 3000000,
+    "areaId": 0,
+    "value": 16,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 4000000,
+    "areaId": 0,
+    "value": 10,
+    "prop": 289408000
+  }
+]
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json
new file mode 100644
index 0000000..98232c6
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json
@@ -0,0 +1 @@
+{
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 2aa949a..dee36f4 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -32,6 +32,7 @@
 namespace hardware {
 namespace automotive {
 namespace vehicle {
+namespace fake {
 
 class FakeVehicleHardware final : public IVehicleHardware {
   public:
@@ -94,6 +95,7 @@
     OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock);
 };
 
+}  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 1c06ba0..f8bf7de 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -28,6 +28,7 @@
 namespace hardware {
 namespace automotive {
 namespace vehicle {
+namespace fake {
 
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
@@ -200,6 +201,7 @@
     }
 }
 
+}  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 650a131..53e647d 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -24,6 +24,7 @@
 namespace hardware {
 namespace automotive {
 namespace vehicle {
+namespace fake {
 
 namespace {
 
@@ -423,6 +424,7 @@
     ASSERT_EQ(getGetValueResults()[1].prop->status, VehiclePropertyStatus::AVAILABLE);
 }
 
+}  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 545cf6a..9da2b14 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -17,6 +17,8 @@
 #ifndef android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
 #define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
 
+#include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
 #include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceState.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceType.h>