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

Commit 23fcad97 authored by Yu Shan's avatar Yu Shan
Browse files

Use FakeUserHal in FakeVehicleHardware.

Handle fake user hal properties in FakeVehicleHardware.

Test: atest FakeVehicleHardwareTest
Bug: 201830716

Change-Id: Ia60bbf7ae6a0fc5909dc8d27363af5c9939055d3
parent 7ed3aeb6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
    },
    {
      "name": "FakeObd2FrameTest"
    },
    {
      "name": "FakeUserHalTest"
    }
  ]
}
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ cc_library {
        "VehicleHalUtils",
        "FakeVehicleHalValueGenerators",
        "FakeObd2Frame",
        "FakeUserHal",
    ],
    shared_libs: [
        "libjsoncpp",
+9 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <DefaultConfig.h>
#include <FakeObd2Frame.h>
#include <FakeUserHal.h>
#include <IVehicleHardware.h>
#include <VehicleHalTypes.h>
#include <VehiclePropertyStore.h>
@@ -91,6 +92,7 @@ class FakeVehicleHardware final : public IVehicleHardware {
    const std::shared_ptr<VehiclePropValuePool> mValuePool;
    const std::shared_ptr<VehiclePropertyStore> mServerSidePropStore;
    const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
    const std::unique_ptr<FakeUserHal> mFakeUserHal;
    std::mutex mCallbackLock;
    OnPropertyChangeCallback mOnPropertyChangeCallback GUARDED_BY(mCallbackLock);
    OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock);
@@ -107,16 +109,21 @@ class FakeVehicleHardware final : public IVehicleHardware {
    // Override the properties using config files in 'overrideDir'.
    void overrideProperties(const char* overrideDir);

    ::aidl::android::hardware::automotive::vehicle::StatusCode maybeSetSpecialValue(
    ::android::base::Result<void> maybeSetSpecialValue(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
            bool* isSpecialValue);
    ::android::base::Result<VehiclePropValuePool::RecyclableType> maybeGetSpecialValue(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
            bool* isSpecialValue) const;
    ::aidl::android::hardware::automotive::vehicle::StatusCode setApPowerStateReport(
    ::android::base::Result<void> setApPowerStateReport(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
    VehiclePropValuePool::RecyclableType createApPowerStateReq(
            ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state);
    ::android::base::Result<void> setUserHalProp(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
    ::android::base::Result<VehiclePropValuePool::RecyclableType> getUserHalProp(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
    bool isHvacPropAndHvacNotAvailable(int32_t propId);
};

}  // namespace fake
+116 −40
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <fstream>
#include <regex>
#include <unordered_set>
#include <vector>

namespace android {
@@ -55,6 +56,7 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;

using ::android::base::Error;
using ::android::base::Result;

const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
@@ -68,6 +70,11 @@ StatusCode getErrorCode(const Result<T>& result) {
    return static_cast<StatusCode>(result.error().code());
}

template <class T>
int getIntErrorCode(const Result<T>& result) {
    return toInt(getErrorCode(result));
}

template <class T>
std::string getErrorMsg(const Result<T>& result) {
    if (result.ok()) {
@@ -114,7 +121,7 @@ void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDecla
                mServerSidePropStore->writeValue(mValuePool->obtain(prop), /*updateStatus=*/true);
        if (!result.ok()) {
            ALOGE("failed to write default config value, error: %s, status: %d",
                  getErrorMsg(result).c_str(), getErrorCode(result));
                  getErrorMsg(result).c_str(), getIntErrorCode(result));
        }
    }
}
@@ -122,14 +129,16 @@ void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDecla
FakeVehicleHardware::FakeVehicleHardware()
    : mValuePool(new VehiclePropValuePool),
      mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
      mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)) {
      mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
      mFakeUserHal(new FakeUserHal(mValuePool)) {
    init();
}

FakeVehicleHardware::FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool)
    : mValuePool(std::move(valuePool)),
      mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
      mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)) {
      mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
      mFakeUserHal(new FakeUserHal(mValuePool)) {
    init();
}

@@ -179,16 +188,14 @@ VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq(
    return req;
}

StatusCode FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
Result<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
    auto updatedValue = mValuePool->obtain(value);
    updatedValue->timestamp = elapsedRealtimeNano();

    if (auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
        !writeResult.ok()) {
        StatusCode errorCode = getErrorCode(writeResult);
        ALOGE("failed to write value into property store, error: %s, code: %d",
              getErrorMsg(writeResult).c_str(), errorCode);
        return errorCode;
        return Error(getIntErrorCode(writeResult))
               << "failed to write value into property store, error: " << getErrorMsg(writeResult);
    }

    VehiclePropValuePool::RecyclableType prop;
@@ -208,10 +215,9 @@ StatusCode FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& va
            if (auto writeResult =
                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
                !writeResult.ok()) {
                StatusCode errorCode = getErrorCode(writeResult);
                ALOGE("failed to write AP_POWER_STATE_REQ into property store, error: %s, code: %d",
                      getErrorMsg(writeResult).c_str(), errorCode);
                return errorCode;
                return Error(getIntErrorCode(writeResult))
                       << "failed to write AP_POWER_STATE_REQ into property store, error: "
                       << getErrorMsg(writeResult);
            }
            break;
        case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
@@ -226,17 +232,73 @@ StatusCode FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& va
            if (auto writeResult =
                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
                !writeResult.ok()) {
                StatusCode errorCode = getErrorCode(writeResult);
                ALOGE("failed to write AP_POWER_STATE_REQ into property store, error: %s, code: %d",
                      getErrorMsg(writeResult).c_str(), errorCode);
                return errorCode;
                return Error(getIntErrorCode(writeResult))
                       << "failed to write AP_POWER_STATE_REQ into property store, error: "
                       << getErrorMsg(writeResult);
            }
            break;
        default:
            ALOGE("Unknown VehicleApPowerStateReport: %d", state);
            break;
    }
    return StatusCode::OK;
    return {};
}

bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
    std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
                                           std::end(HVAC_POWER_PROPERTIES));
    if (powerProps.count(propId)) {
        auto hvacPowerOnResult =
                mServerSidePropStore->readValue(toInt(VehicleProperty::HVAC_POWER_ON), HVAC_ALL);

        if (hvacPowerOnResult.ok() && hvacPowerOnResult.value()->value.int32Values.size() == 1 &&
            hvacPowerOnResult.value()->value.int32Values[0] == 0) {
            return true;
        }
    }
    return false;
}

Result<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& value) {
    auto result = mFakeUserHal->onSetProperty(value);
    if (!result.ok()) {
        return Error(getIntErrorCode(result))
               << "onSetProperty(): HAL returned error: " << getErrorMsg(result);
    }
    auto& updatedValue = result.value();
    if (updatedValue != nullptr) {
        ALOGI("onSetProperty(): updating property returned by HAL: %s",
              updatedValue->toString().c_str());
        if (auto writeResult = mServerSidePropStore->writeValue(std::move(result.value()));
            !writeResult.ok()) {
            return Error(getIntErrorCode(writeResult))
                   << "failed to write value into property store, error: "
                   << getErrorMsg(writeResult);
        }
    }
    return {};
}

Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::getUserHalProp(
        const VehiclePropValue& value) const {
    auto propId = value.prop;
    ALOGI("get(): getting value for prop %d from User HAL", propId);

    auto result = mFakeUserHal->onGetProperty(value);
    if (!result.ok()) {
        return Error(getIntErrorCode(result))
               << "get(): User HAL returned error: " << getErrorMsg(result);
    } else {
        auto& gotValue = result.value();
        if (gotValue != nullptr) {
            ALOGI("get(): User HAL returned value: %s", gotValue->toString().c_str());
            gotValue->timestamp = elapsedRealtimeNano();
            return result;
        } else {
            return Error(toInt(StatusCode::INTERNAL_ERROR))
                   << "get(): User HAL returned null value";
        }
    }
}

Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::maybeGetSpecialValue(
@@ -245,6 +307,11 @@ Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::maybeGetSpecia
    int32_t propId = value.prop;
    Result<VehiclePropValuePool::RecyclableType> result;

    if (mFakeUserHal->isSupported(propId)) {
        *isSpecialValue = true;
        return getUserHalProp(value);
    }

    switch (propId) {
        case OBD2_FREEZE_FRAME:
            *isSpecialValue = true;
@@ -268,12 +335,23 @@ Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::maybeGetSpecia
    return nullptr;
}

StatusCode FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
Result<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
                                                       bool* isSpecialValue) {
    *isSpecialValue = false;
    VehiclePropValuePool::RecyclableType updatedValue;
    int32_t propId = value.prop;

    if (mFakeUserHal->isSupported(propId)) {
        *isSpecialValue = true;
        return setUserHalProp(value);
    }

    switch (value.prop) {
    if (isHvacPropAndHvacNotAvailable(propId)) {
        *isSpecialValue = true;
        return Error(toInt(StatusCode::NOT_AVAILABLE)) << "hvac not available";
    }

    switch (propId) {
        case toInt(VehicleProperty::AP_POWER_STATE_REPORT):
            *isSpecialValue = true;
            return setApPowerStateReport(value);
@@ -281,7 +359,7 @@ StatusCode FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& val
            // Placeholder for future implementation of VMS property in the default hal. For
            // now, just returns OK; otherwise, hal clients crash with property not supported.
            *isSpecialValue = true;
            return StatusCode::OK;
            return {};
        case OBD2_FREEZE_FRAME_CLEAR:
            *isSpecialValue = true;
            return mFakeObd2Frame->clearObd2FreezeFrames(value);
@@ -309,18 +387,17 @@ StatusCode FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& val
            updatedValue->areaId = value.areaId;
            if (auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
                !writeResult.ok()) {
                StatusCode errorCode = getErrorCode(writeResult);
                ALOGE("failed to write value into property store, error: %s, code: %d",
                      getErrorMsg(writeResult).c_str(), errorCode);
                return errorCode;
                return Error(getIntErrorCode(writeResult))
                       << "failed to write value into property store, error: "
                       << getErrorMsg(writeResult);
            }
            return StatusCode::OK;
            return {};
#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING

        default:
            break;
    }
    return StatusCode::OK;
    return {};
}

StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&& callback,
@@ -338,13 +415,14 @@ StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback
        setValueResult.status = StatusCode::OK;

        bool isSpecialValue = false;
        StatusCode status = maybeSetSpecialValue(value, &isSpecialValue);
        auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);

        if (isSpecialValue) {
            if (status != StatusCode::OK) {
                ALOGE("failed to set special value for property ID: %d, status: %d", propId,
                      status);
                setValueResult.status = status;
            if (!setSpecialValueResult.ok()) {
                ALOGE("failed to set special value for property ID: %d, error: %s, status: %d",
                      propId, getErrorMsg(setSpecialValueResult).c_str(),
                      getIntErrorCode(setSpecialValueResult));
                setValueResult.status = getErrorCode(setSpecialValueResult);
            }

            // Special values are already handled.
@@ -358,10 +436,9 @@ StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback

        auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
        if (!writeResult.ok()) {
            StatusCode errorCode = getErrorCode(writeResult);
            ALOGE("failed to write value into property store, error: %s, code: %d",
                  getErrorMsg(writeResult).c_str(), errorCode);
            setValueResult.status = errorCode;
                  getErrorMsg(writeResult).c_str(), getIntErrorCode(writeResult));
            setValueResult.status = getErrorCode(writeResult);
        }
        results.push_back(std::move(setValueResult));
    }
@@ -387,10 +464,9 @@ StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback
        auto result = maybeGetSpecialValue(value, &isSpecialValue);
        if (isSpecialValue) {
            if (!result.ok()) {
                StatusCode errorCode = getErrorCode(result);
                ALOGE("failed to get special value: %d, error: %s, code: %d", value.prop,
                      getErrorMsg(result).c_str(), errorCode);
                getValueResult.status = errorCode;
                      getErrorMsg(result).c_str(), getIntErrorCode(result));
                getValueResult.status = getErrorCode(result);
            } else {
                getValueResult.status = StatusCode::OK;
                getValueResult.prop = *result.value();
@@ -406,7 +482,7 @@ StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback
                ALOGW("%s", "value has not been set yet");
            } else {
                ALOGE("failed to get value, error: %s, code: %d", getErrorMsg(readResult).c_str(),
                      errorCode);
                      toInt(errorCode));
            }
            getValueResult.status = errorCode;
        } else {
@@ -476,7 +552,7 @@ void FakeVehicleHardware::overrideProperties(const char* overrideDir) {
                                                                   /*updateStatus=*/true);
                    !result.ok()) {
                    ALOGW("failed to write vendor override properties: %d, error: %s, code: %d",
                          prop.prop, getErrorMsg(result).c_str(), getErrorCode(result));
                          prop.prop, getErrorMsg(result).c_str(), getIntErrorCode(result));
                }
            }
        }
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ cc_test {
        "FakeVehicleHardware",
        "FakeVehicleHalValueGenerators",
        "FakeObd2Frame",
        "FakeUserHal",
        "libgtest",
        "libgmock",
    ],
Loading