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

Commit cf67ed6f authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I3ac93815,I35dd253e,I274d4480 into main

* changes:
  Add additional HVAC_POWER_ON dependent properties
  Use HVAC_POWER_ON config array for determining power dependent props
  Send CarPropertyValue status when HVAC power state changes
parents 51a8f77c 325527ba
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -1899,8 +1899,16 @@
                }
            ],
            "configArray": [
                "VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM",
                "VehicleProperty::HVAC_AC_ON",
                "VehicleProperty::HVAC_AUTO_ON",
                "VehicleProperty::HVAC_AUTO_RECIRC_ON",
                "VehicleProperty::HVAC_FAN_DIRECTION",
                "VehicleProperty::HVAC_FAN_SPEED",
                "VehicleProperty::HVAC_FAN_DIRECTION"
                "VehicleProperty::HVAC_MAX_AC_ON",
                "VehicleProperty::HVAC_RECIRC_ON",
                "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
                "VehicleProperty::HVAC_TEMPERATURE_SET"
            ]
        },
        {
+5 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <memory>
#include <mutex>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace android {
@@ -161,6 +162,9 @@ class FakeVehicleHardware : public IVehicleHardware {
                                  aidl::android::hardware::automotive::vehicle::SetValueRequest>
            mPendingSetValueRequests;

    // Set of HVAC properties dependent on HVAC_POWER_ON
    std::unordered_set<int32_t> hvacPowerDependentProps;

    const bool mForceOverride;
    bool mAddExtraTestVendorConfigs;

@@ -253,7 +257,7 @@ class FakeVehicleHardware : public IVehicleHardware {
            const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);

    std::string genFakeDataCommand(const std::vector<std::string>& options);
    void sendHvacPropertiesCurrentValues(int32_t areaId);
    void sendHvacPropertiesCurrentValues(int32_t areaId, int32_t hvacPowerOnVal);
    void sendAdasPropertiesState(int32_t propertyId, int32_t state);
    void generateVendorConfigs(
            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const;
+20 −14
Original line number Diff line number Diff line
@@ -200,6 +200,11 @@ void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config)
    bool globalProp = isGlobalProp(propId);
    size_t numAreas = globalProp ? 1 : vehiclePropConfig.areaConfigs.size();

    if (propId == toInt(VehicleProperty::HVAC_POWER_ON)) {
        const auto& configArray = vehiclePropConfig.configArray;
        hvacPowerDependentProps.insert(configArray.begin(), configArray.end());
    }

    for (size_t i = 0; i < numAreas; i++) {
        int32_t curArea = globalProp ? 0 : vehiclePropConfig.areaConfigs[i].areaId;

@@ -511,9 +516,7 @@ VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
}

bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const {
    std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
                                           std::end(HVAC_POWER_PROPERTIES));
    if (powerProps.count(propId)) {
    if (hvacPowerDependentProps.count(propId)) {
        auto hvacPowerOnResults =
                mServerSidePropStore->readValuesForProperty(toInt(VehicleProperty::HVAC_POWER_ON));
        if (!hvacPowerOnResults.ok()) {
@@ -731,9 +734,8 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::getEchoReverseBytes(
    return std::move(gotValue);
}

void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) {
    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
        int powerPropId = HVAC_POWER_PROPERTIES[i];
void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId, int32_t hvacPowerOnVal) {
    for (auto& powerPropId : hvacPowerDependentProps) {
        auto powerPropResults = mServerSidePropStore->readValuesForProperty(powerPropId);
        if (!powerPropResults.ok()) {
            ALOGW("failed to get power prop 0x%x, error: %s", powerPropId,
@@ -744,7 +746,8 @@ void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) {
        for (size_t j = 0; j < powerPropValues.size(); j++) {
            auto powerPropValue = std::move(powerPropValues[j]);
            if ((powerPropValue->areaId & areaId) == powerPropValue->areaId) {
                powerPropValue->status = VehiclePropertyStatus::AVAILABLE;
                powerPropValue->status = hvacPowerOnVal ? VehiclePropertyStatus::AVAILABLE
                                                        : VehiclePropertyStatus::UNAVAILABLE;
                powerPropValue->timestamp = elapsedRealtimeNano();
                // This will trigger a property change event for the current hvac property value.
                mServerSidePropStore->writeValue(std::move(powerPropValue), /*updateStatus=*/true,
@@ -796,13 +799,6 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu
        return setUserHalProp(value);
    }

    if (propId == toInt(VehicleProperty::HVAC_POWER_ON) && value.value.int32Values.size() == 1 &&
        value.value.int32Values[0] == 1) {
        // If we are turning HVAC power on, send current hvac property values through on change
        // event.
        sendHvacPropertiesCurrentValues(value.areaId);
    }

    if (isHvacPropAndHvacNotAvailable(propId, value.areaId)) {
        *isSpecialValue = true;
        return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) << "hvac not available";
@@ -841,6 +837,16 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu
        case toInt(TestVendorProperty::VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING):
            *isSpecialValue = true;
            return StatusError((StatusCode)VENDOR_ERROR_CODE);
        case toInt(VehicleProperty::HVAC_POWER_ON):
            if (value.value.int32Values.size() != 1) {
                *isSpecialValue = true;
                return StatusError(StatusCode::INVALID_ARG)
                       << "HVAC_POWER_ON requires only one int32 value";
            }
            // When changing HVAC power state, send current hvac property values
            // through on change event.
            sendHvacPropertiesCurrentValues(value.areaId, value.value.int32Values[0]);
            return {};
        case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION):
            *isSpecialValue = true;
            return setHvacTemperatureValueSuggestion(value);
+109 −49
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <inttypes.h>
#include <chrono>
#include <condition_variable>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -78,7 +79,9 @@ using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
using ::android::base::expected;
@@ -109,6 +112,10 @@ class FakeVehicleHardwareTestHelper {
        return mHardware->loadConfigDeclarations();
    }

    std::unordered_set<int32_t> getHvacPowerDependentProps() {
        return mHardware->hvacPowerDependentProps;
    }

  private:
    FakeVehicleHardware* mHardware;
};
@@ -390,6 +397,25 @@ class FakeVehicleHardwareTest : public ::testing::Test {
        }
    } mPropValueCmp;

    std::unique_ptr<VehiclePropConfig> getVehiclePropConfig(int32_t propertyId) {
        auto configs = mHardware->getAllPropertyConfigs();
        for (auto& config : configs) {
            if (config.prop == propertyId) {
                auto ptr = std::make_unique<VehiclePropConfig>();
                ptr->prop = config.prop;
                ptr->access = config.access;
                ptr->changeMode = config.changeMode;
                ptr->areaConfigs = config.areaConfigs;
                ptr->configArray = config.configArray;
                ptr->configString = config.configString;
                ptr->minSampleRate = config.minSampleRate;
                ptr->maxSampleRate = config.maxSampleRate;
                return ptr;
            }
        }
        return std::unique_ptr<VehiclePropConfig>(nullptr);
    }

  private:
    std::unique_ptr<FakeVehicleHardware> mHardware;
    std::shared_ptr<IVehicleHardware::SetValuesCallback> mSetValuesCallback;
@@ -1687,23 +1713,35 @@ TEST_F(FakeVehicleHardwareTest, testSetVehicleMapService) {
}

TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
    for (int areaId : seatAreaIds) {
    FakeVehicleHardwareTestHelper helper(getHardware());
    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
    EXPECT_NE(hvacPowerOnConfig, nullptr);
    for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
        int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
        // Turn off HVAC_POWER_ON for only 1 area ID
        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                      .areaId = areaId,
                                                      .areaId = hvacPowerAreaId,
                                                      .value.int32Values = {0}});
        EXPECT_EQ(status, StatusCode::OK);

        ASSERT_EQ(status, StatusCode::OK);

        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
            int powerPropId = HVAC_POWER_PROPERTIES[i];
            for (int powerDependentAreaId : seatAreaIds) {
        for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
            auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
            EXPECT_NE(powerPropConfig, nullptr);
            if (powerPropConfig->access == VehiclePropertyAccess::WRITE) {
                continue;
            }
            // Try getting a value at each area ID supported by the power dependent property
            for (auto& powerPropAreaConfig : powerPropConfig->areaConfigs) {
                int powerDependentAreaId = powerPropAreaConfig.areaId;
                auto getValueResult = getValue(VehiclePropValue{
                        .prop = powerPropId,
                        .areaId = powerDependentAreaId,
                });

                if (areaId == powerDependentAreaId) {
                // If the current area ID is contained within the HVAC_POWER_ON area ID
                // turned off, then getValue should fail and a StatusCode error should be
                // returned. Otherwise, a value should be returned.
                if ((hvacPowerAreaId & powerDependentAreaId) == powerDependentAreaId) {
                    EXPECT_FALSE(getValueResult.ok());
                    EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE_DISABLED);
                } else {
@@ -1716,28 +1754,45 @@ TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
        // on this value from any power dependent property values other than those with the same
        // areaId.
        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                  .areaId = areaId,
                                  .areaId = hvacPowerAreaId,
                                  .value.int32Values = {1}});
    }
}

TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
    for (int areaId : seatAreaIds) {
    FakeVehicleHardwareTestHelper helper(getHardware());
    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
    EXPECT_NE(hvacPowerOnConfig, nullptr);
    for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
        int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
        // Turn off HVAC_POWER_ON for only 1 area ID
        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                      .areaId = areaId,
                                                      .areaId = hvacPowerAreaId,
                                                      .value.int32Values = {0}});
        EXPECT_EQ(status, StatusCode::OK);

        ASSERT_EQ(status, StatusCode::OK);

        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
            int powerPropId = HVAC_POWER_PROPERTIES[i];
            for (int powerDependentAreaId : seatAreaIds) {
                StatusCode status = setValue(VehiclePropValue{.prop = powerPropId,
                                                              .areaId = powerDependentAreaId,
                                                              .value.int32Values = {1}});
        for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
            auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
            EXPECT_NE(powerPropConfig, nullptr);
            if (powerPropConfig->access == VehiclePropertyAccess::READ) {
                continue;
            }
            auto propType = getPropType(powerPropId);
            // Try setting a value at each area ID supported by the power dependent property
            for (auto& powerPropAreaConfig : powerPropConfig->areaConfigs) {
                int powerDependentAreaId = powerPropAreaConfig.areaId;
                auto val = VehiclePropValue{.prop = powerPropId, .areaId = powerDependentAreaId};
                if (propType == VehiclePropertyType::FLOAT) {
                    val.value.floatValues.emplace_back(20);
                } else {
                    val.value.int32Values.emplace_back(1);
                }
                status = setValue(val);

                if (areaId == powerDependentAreaId) {
                // If the current area ID is contained within the HVAC_POWER_ON area ID
                // turned off, then setValue should fail and a StatusCode error should be
                // returned. Otherwise, an ok StatusCode should be returned.
                if ((hvacPowerAreaId & powerDependentAreaId) == powerDependentAreaId) {
                    EXPECT_EQ(status, StatusCode::NOT_AVAILABLE_DISABLED);
                } else {
                    EXPECT_EQ(status, StatusCode::OK);
@@ -1749,38 +1804,48 @@ TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
        // on this value from any power dependent property values other than those with the same
        // areaId.
        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                  .areaId = areaId,
                                  .areaId = hvacPowerAreaId,
                                  .value.int32Values = {1}});
    }
}

TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
    for (int areaId : seatAreaIds) {
    FakeVehicleHardwareTestHelper helper(getHardware());
    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
    EXPECT_NE(hvacPowerOnConfig, nullptr);
    for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
        int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                      .areaId = areaId,
                                                      .areaId = hvacPowerAreaId,
                                                      .value.int32Values = {0}});

        ASSERT_EQ(status, StatusCode::OK);

        clearChangedProperties();
        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                  .areaId = areaId,
                                  .value.int32Values = {1}});

        EXPECT_EQ(status, StatusCode::OK);
        auto events = getChangedProperties();
        // If we turn HVAC power on, we expect to receive one property event for every HVAC prop
        // areas plus one event for HVAC_POWER_ON.
        std::vector<int32_t> changedPropIds;
        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
            changedPropIds.push_back(HVAC_POWER_PROPERTIES[i]);
        for (const auto& event : events) {
            // Ignore HVAC_POWER_ON event
            if (event.prop == toInt(VehicleProperty::HVAC_POWER_ON)) {
                continue;
            }
            EXPECT_THAT(event.prop, AnyOfArray(helper.getHvacPowerDependentProps()));
            EXPECT_EQ((hvacPowerAreaId & event.areaId), hvacPowerAreaId);
            EXPECT_EQ(event.status, VehiclePropertyStatus::UNAVAILABLE);
        }
        changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON));
        clearChangedProperties();

        status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                           .areaId = hvacPowerAreaId,
                                           .value.int32Values = {1}});
        EXPECT_EQ(status, StatusCode::OK);
        events = getChangedProperties();
        for (const auto& event : events) {
            EXPECT_EQ(event.areaId, areaId);
            EXPECT_THAT(event.prop, AnyOfArray(changedPropIds));
            // Ignore HVAC_POWER_ON event
            if (event.prop == toInt(VehicleProperty::HVAC_POWER_ON)) {
                continue;
            }
            EXPECT_THAT(event.prop, AnyOfArray(helper.getHvacPowerDependentProps()));
            EXPECT_EQ((hvacPowerAreaId & event.areaId), hvacPowerAreaId);
            EXPECT_EQ(event.status, VehiclePropertyStatus::AVAILABLE);
        }
        clearChangedProperties();
    }
}

@@ -3016,13 +3081,8 @@ TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {

    // Config array values from HVAC_TEMPERATURE_SET in DefaultProperties.json
    auto configs = getHardware()->getAllPropertyConfigs();
    VehiclePropConfig* hvacTemperatureSetConfig = nullptr;
    for (auto& config : configs) {
        if (config.prop == toInt(VehicleProperty::HVAC_TEMPERATURE_SET)) {
            hvacTemperatureSetConfig = &config;
            break;
        }
    }
    auto hvacTemperatureSetConfig =
            std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
    EXPECT_NE(hvacTemperatureSetConfig, nullptr);

    auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfig->configArray;
+0 −5
Original line number Diff line number Diff line
@@ -98,11 +98,6 @@ constexpr int HVAC_LEFT = SEAT_1_LEFT | SEAT_2_LEFT | SEAT_2_CENTER;
constexpr int HVAC_RIGHT = SEAT_1_RIGHT | SEAT_2_RIGHT;
constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;

const int32_t HVAC_POWER_PROPERTIES[] = {
        toInt(propertyutils_impl::VehicleProperty::HVAC_FAN_SPEED),
        toInt(propertyutils_impl::VehicleProperty::HVAC_FAN_DIRECTION),
};

}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware