Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5753b07c authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4778776 from 68995cb3 to pi-release

Change-Id: Ibe87ea0251977289fedeb848e0672be46e48fac1
parents 0541524e 68995cb3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ cc_library_static {
        "impl/vhal_v2_0/VehicleEmulator.cpp",
        "impl/vhal_v2_0/PipeComm.cpp",
        "impl/vhal_v2_0/SocketComm.cpp",
        "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
        "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
    ],
    local_include_dirs: ["common/include/vhal_v2_0"],
    export_include_dirs: ["impl"],
@@ -71,6 +73,7 @@ cc_library_static {
        "libprotobuf-cpp-lite",
    ],
    static_libs: [
        "libjsoncpp",
        "libqemu_pipe",
        "android.hardware.automotive.vehicle@2.0-libproto-native",
    ],
@@ -107,6 +110,7 @@ cc_binary {
        "android.hardware.automotive.vehicle@2.0-manager-lib",
        "android.hardware.automotive.vehicle@2.0-default-impl-lib",
        "android.hardware.automotive.vehicle@2.0-libproto-native",
        "libjsoncpp",
        "libqemu_pipe",
    ],
}
+45 −17
Original line number Diff line number Diff line
@@ -42,38 +42,66 @@ constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK;
constexpr int ALL_WHEELS =
    (int)(Wheel::LEFT_FRONT | Wheel::RIGHT_FRONT | Wheel::LEFT_REAR | Wheel::RIGHT_REAR);

/*
 * This property is used for test purpose to generate fake events.
 *
 * It has the following format:
 *
 * int32Values[0] - command (see FakeDataCommand below for possible values)
 * int32Values[1] - VehicleProperty to which command applies
/**
 * This property is used for test purpose to generate fake events. Here is the test package that
 * is referencing this property definition: packages/services/Car/tests/vehiclehal_test
 */
const int32_t kGenerateFakeDataControllingProperty =
    0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;

/**
 * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty.
 * All those commands can be send independently with each other. And each will override the one sent
 * previously.
 *
 * The controlling property has the following format:
 *
 *     int32Values[0] - command enum defined in FakeDataCommand
 *
 * The format of the arguments is defined for each command type as below:
 */
enum class FakeDataCommand : int32_t {
    /** Stops generating of fake data that was triggered by Start command */
    Stop = 0,

    /**
     * Starts fake data generation.  Caller must provide additional data:
     * Starts linear fake data generation. Caller must provide additional data:
     *     int32Values[1] - VehicleProperty to which command applies
     *     int64Values[0] - periodic interval in nanoseconds
     *     floatValues[0] - initial value
     *     floatValues[1] - dispersion defines min and max range relative to initial value
     *     floatValues[1] - dispersion defines the min/max value relative to initial value, where
     *                      max = initial_value + dispersion, min = initial_value - dispersion.
     *                      Dispersion should be non-negative, otherwise the behavior is undefined.
     *     floatValues[2] - increment, with every timer tick the value will be incremented by this
     * amount
     *                      amount. When reaching to max value, the current value will be set to min.
     *                      It should be non-negative, otherwise the behavior is undefined.
     */
    StartLinear = 0,

    /** Stops generating of fake data that was triggered by Start commands.
     *     int32Values[1] - VehicleProperty to which command applies. VHAL will stop the
     *                      corresponding linear generation for that property.
     */
    StopLinear = 1,

    /**
     * Starts JSON-based fake data generation. Caller must provide a string value specifying
     * the path to fake value JSON file:
     *     stringValue    - path to the fake values JSON file
     */
    StartJson = 2,

    /**
     * Stops JSON-based fake data generation. No additional arguments needed.
     */
    Start = 1,
    StopJson = 3,

    /**
     * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every
     * key-press). Caller must provide the following data: int32Values[2] - Android key code
     * key-press). We set the enum with high number to leave space for future start/stop commands.
     * Caller must provide the following data:
     *     int32Values[2] - Android key code
     *     int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see
     *                      VehicleDisplay)
     */
    KeyPress = 2,
    KeyPress = 100,
};

const int32_t kHvacPowerProperties[] = {
+28 −52
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <android-base/macros.h>

#include "EmulatedVehicleHal.h"
#include "JsonFakeValueGenerator.h"
#include "LinearFakeValueGenerator.h"
#include "Obd2SensorStore.h"

namespace android {
@@ -88,10 +90,12 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt
EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore)
    : mPropStore(propStore),
      mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
      mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer,
                                  this, std::placeholders::_1)),
      mFakeValueGenerator(std::bind(&EmulatedVehicleHal::onFakeValueGenerated,
                                    this, std::placeholders::_1, std::placeholders::_2)) {
      mRecurrentTimer(
          std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)),
      mLinearFakeValueGenerator(std::make_unique<LinearFakeValueGenerator>(
          std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))),
      mJsonFakeValueGenerator(std::make_unique<JsonFakeValueGenerator>(
          std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))) {
    initStaticConfig();
    for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
        mPropStore->registerProperty(kVehicleProperties[i].config);
@@ -328,42 +332,29 @@ std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const {
StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
    ALOGI("%s", __func__);
    const auto& v = request.value;
    if (v.int32Values.size() < 2) {
        ALOGE("%s: expected at least 2 elements in int32Values, got: %zu", __func__,
                v.int32Values.size());
    if (!v.int32Values.size()) {
        ALOGE("%s: expected at least \"command\" field in int32Values", __func__);
        return StatusCode::INVALID_ARG;
    }

    FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]);
    int32_t propId = v.int32Values[1];

    switch (command) {
        case FakeDataCommand::Start: {
            if (!v.int64Values.size()) {
                ALOGE("%s: interval is not provided in int64Values", __func__);
                return StatusCode::INVALID_ARG;
        case FakeDataCommand::StartLinear: {
            ALOGI("%s, FakeDataCommand::StartLinear", __func__);
            return mLinearFakeValueGenerator->start(request);
        }
            auto interval = std::chrono::nanoseconds(v.int64Values[0]);

            if (v.floatValues.size() < 3) {
                ALOGE("%s: expected at least 3 element sin floatValues, got: %zu", __func__,
                        v.floatValues.size());
                return StatusCode::INVALID_ARG;
        case FakeDataCommand::StartJson: {
            ALOGI("%s, FakeDataCommand::StartJson", __func__);
            return mJsonFakeValueGenerator->start(request);
        }
            float initialValue = v.floatValues[0];
            float dispersion = v.floatValues[1];
            float increment = v.floatValues[2];

            ALOGI("%s, propId: %d, initalValue: %f", __func__, propId, initialValue);
            mFakeValueGenerator.startGeneratingHalEvents(
                interval, propId, initialValue, dispersion, increment);

            break;
        case FakeDataCommand::StopLinear: {
            ALOGI("%s, FakeDataCommand::StopLinear", __func__);
            return mLinearFakeValueGenerator->stop(request);
        }
        case FakeDataCommand::Stop: {
            ALOGI("%s, FakeDataCommand::Stop", __func__);
            mFakeValueGenerator.stopGeneratingHalEvents(propId);
            break;
        case FakeDataCommand::StopJson: {
            ALOGI("%s, FakeDataCommand::StopJson", __func__);
            return mJsonFakeValueGenerator->stop(request);
        }
        case FakeDataCommand::KeyPress: {
            ALOGI("%s, FakeDataCommand::KeyPress", __func__);
@@ -374,7 +365,6 @@ StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropVa
            doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
            break;
        }

        default: {
            ALOGE("%s: unexpected command: %d", __func__, command);
            return StatusCode::INVALID_ARG;
@@ -396,30 +386,16 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp(
    return keyEvent;
}

void EmulatedVehicleHal::onFakeValueGenerated(int32_t propId, float value) {
void EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) {
    ALOGD("%s: %s", __func__, toString(value).c_str());
    static constexpr bool shouldUpdateStatus = false;

    VehiclePropValuePtr updatedPropValue {};
    switch (getPropType(propId)) {
        case VehiclePropertyType::FLOAT:
            updatedPropValue = getValuePool()->obtainFloat(value);
            break;
        case VehiclePropertyType::INT32:
            updatedPropValue = getValuePool()->obtainInt32(static_cast<int32_t>(value));
            break;
        default:
            ALOGE("%s: data type for property: 0x%x not supported", __func__, propId);
            return;

    }

    VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
    if (updatedPropValue) {
        updatedPropValue->prop = propId;
        updatedPropValue->areaId = 0;  // Add area support if necessary.
        updatedPropValue->timestamp = elapsedRealtimeNano();
        updatedPropValue->status = VehiclePropertyStatus::AVAILABLE;
        mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus);
        auto changeMode = mPropStore->getConfigOrDie(propId)->changeMode;
        auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode;
        if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) {
            doHalEvent(move(updatedPropValue));
        }
+5 −3
Original line number Diff line number Diff line
@@ -30,9 +30,10 @@
#include "vhal_v2_0/VehiclePropertyStore.h"

#include "DefaultConfig.h"
#include "VehicleEmulator.h"
#include "FakeValueGenerator.h"

#include "VehicleEmulator.h"

namespace android {
namespace hardware {
namespace automotive {
@@ -66,7 +67,7 @@ private:
    }

    StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
    void onFakeValueGenerated(int32_t propId, float value);
    void onFakeValueGenerated(const VehiclePropValue& value);
    VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
                                             int32_t targetDisplay);

@@ -84,7 +85,8 @@ private:
    VehiclePropertyStore* mPropStore;
    std::unordered_set<int32_t> mHvacPowerProps;
    RecurrentTimer mRecurrentTimer;
    FakeValueGenerator mFakeValueGenerator;
    std::unique_ptr<FakeValueGenerator> mLinearFakeValueGenerator;
    std::unique_ptr<FakeValueGenerator> mJsonFakeValueGenerator;
};

}  // impl
+20 −88
Original line number Diff line number Diff line
@@ -14,15 +14,11 @@
 * limitations under the License.
 */

#ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
#define android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_

#include <chrono>
#ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_
#define android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_

#include <android/hardware/automotive/vehicle/2.0/types.h>

#include <vhal_v2_0/RecurrentTimer.h>

namespace android {
namespace hardware {
namespace automotive {
@@ -31,89 +27,27 @@ namespace V2_0 {

namespace impl {

class FakeValueGenerator {
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 {
        float initialValue;  //
        float currentValue;  //  Should be in range (initialValue +/- 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.
    };

public:
    using OnHalEvent = std::function<void(int32_t propId, float value)>;

    FakeValueGenerator(const OnHalEvent& onHalEvent) :
        mOnHalEvent(onHalEvent),
        mRecurrentTimer(std::bind(&FakeValueGenerator::onTimer, this,
                                  std::placeholders::_1))
    {}

    ~FakeValueGenerator() = default;


    void startGeneratingHalEvents(std::chrono::nanoseconds interval, int propId, float initialValue,
                                  float dispersion, float increment) {
        MuxGuard g(mLock);

        removeLocked(propId);

        mGenCfg.insert({propId, GeneratorCfg {
            .initialValue = initialValue,
            .currentValue = initialValue,
            .dispersion = dispersion,
            .increment = increment,
        }});

        mRecurrentTimer.registerRecurrentEvent(interval, propId);
    }

    void stopGeneratingHalEvents(int propId) {
        MuxGuard g(mLock);
        if (propId == 0) {
            // Remove all.
            for (auto&& it : mGenCfg) {
                removeLocked(it.first);
            }
        } else {
            removeLocked(propId);
        }
    }

private:
    void removeLocked(int propId) {
        if (mGenCfg.erase(propId)) {
            mRecurrentTimer.unregisterRecurrentEvent(propId);
        }
    }

    void onTimer(const std::vector<int32_t>& properties) {
        MuxGuard g(mLock);

        for (int32_t propId : properties) {
            auto& cfg = mGenCfg[propId];
            cfg.currentValue += cfg.increment;
            if (cfg.currentValue > cfg.initialValue + cfg.dispersion) {
                cfg.currentValue = cfg.initialValue - cfg.dispersion;
            }
            mOnHalEvent(propId, cfg.currentValue);
        }
    }

private:
using OnHalEvent = std::function<void(const VehiclePropValue& event)>;
using MuxGuard = std::lock_guard<std::mutex>;

    mutable std::mutex mLock;
    OnHalEvent mOnHalEvent;
    RecurrentTimer mRecurrentTimer;
    std::unordered_map<int32_t, GeneratorCfg> mGenCfg;
class FakeValueGenerator {
public:
    virtual ~FakeValueGenerator() = default;
    /**
     * Starts generating VHAL events
     *
     * @param request in VehiclePropValue with required information to start fake data generation
     * @return StatusCode of the start request
     */
    virtual StatusCode start(const VehiclePropValue& request) = 0;
    /**
     * Stops generating VHAL events
     * @param request in VehiclePropValue with required information to stop fake data generation
     * @return StatusCode of the stop request
     */
    virtual StatusCode stop(const VehiclePropValue& request) = 0;
};


}  // impl

}  // namespace V2_0
@@ -122,6 +56,4 @@ private:
}  // namespace hardware
}  // namespace android



#endif //android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
#endif  // android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_
Loading