diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json index 4a16bf7444..6c8d59ca8c 100644 --- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json +++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json @@ -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" ] }, { 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 e8da43ae47..844bea5a81 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h @@ -36,6 +36,7 @@ #include #include #include +#include #include 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 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& 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&) const; 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 13c48c6e04..ee24fbda9c 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp @@ -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 FakeVehicleHardware::setHvacTemperatureValueSuggestion( } bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const { - std::unordered_set 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 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 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); 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 6cc06bc3ac..cf9beee0fb 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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 getHvacPowerDependentProps() { + return mHardware->hvacPowerDependentProps; + } + private: FakeVehicleHardware* mHardware; }; @@ -390,6 +397,25 @@ class FakeVehicleHardwareTest : public ::testing::Test { } } mPropValueCmp; + std::unique_ptr getVehiclePropConfig(int32_t propertyId) { + auto configs = mHardware->getAllPropertyConfigs(); + for (auto& config : configs) { + if (config.prop == propertyId) { + auto ptr = std::make_unique(); + 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(nullptr); + } + private: std::unique_ptr mHardware; std::shared_ptr 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 (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); - 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}}); - - 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 changedPropIds; - for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) { - changedPropIds.push_back(HVAC_POWER_PROPERTIES[i]); - } - changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON)); - 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::UNAVAILABLE); } + 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) { + // 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; diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h index e41ec3074c..78b61f714e 100644 --- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h +++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h @@ -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