mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 05:49:27 +00:00
Merge "Support hvac temperature synchronization in VHAL" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
3c4646734b
@@ -222,6 +222,9 @@ class FakeVehicleHardware : public IVehicleHardware {
|
||||
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
|
||||
bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const;
|
||||
VhalResult<void> isAdasPropertyAvailable(int32_t adasStatePropertyId) const;
|
||||
VhalResult<void> synchronizeHvacTemp(int32_t hvacDualOnAreaId,
|
||||
std::optional<float> newTempC) const;
|
||||
std::optional<int32_t> getSyncedAreaIdIfHvacDualOn(int32_t hvacTemperatureSetAreaId) const;
|
||||
|
||||
std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
|
||||
|
||||
|
||||
@@ -601,6 +601,65 @@ VhalResult<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& val
|
||||
return {};
|
||||
}
|
||||
|
||||
VhalResult<void> FakeVehicleHardware::synchronizeHvacTemp(int32_t hvacDualOnAreaId,
|
||||
std::optional<float> newTempC) const {
|
||||
auto hvacTemperatureSetResults = mServerSidePropStore->readValuesForProperty(
|
||||
toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
if (!hvacTemperatureSetResults.ok()) {
|
||||
return StatusError(StatusCode::NOT_AVAILABLE)
|
||||
<< "Failed to get HVAC_TEMPERATURE_SET, error: "
|
||||
<< getErrorMsg(hvacTemperatureSetResults);
|
||||
}
|
||||
auto& hvacTemperatureSetValues = hvacTemperatureSetResults.value();
|
||||
std::optional<float> tempCToSynchronize = newTempC;
|
||||
for (size_t i = 0; i < hvacTemperatureSetValues.size(); i++) {
|
||||
int32_t areaId = hvacTemperatureSetValues[i]->areaId;
|
||||
if ((hvacDualOnAreaId & areaId) != areaId) {
|
||||
continue;
|
||||
}
|
||||
if (hvacTemperatureSetValues[i]->status != VehiclePropertyStatus::AVAILABLE) {
|
||||
continue;
|
||||
}
|
||||
// When HVAC_DUAL_ON is initially enabled, synchronize all area IDs
|
||||
// to the temperature of the first area ID, which is the driver's.
|
||||
if (!tempCToSynchronize.has_value()) {
|
||||
tempCToSynchronize = hvacTemperatureSetValues[i]->value.floatValues[0];
|
||||
continue;
|
||||
}
|
||||
auto updatedValue = std::move(hvacTemperatureSetValues[i]);
|
||||
updatedValue->value.floatValues[0] = tempCToSynchronize.value();
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
// This will trigger a property change event for the current hvac property value.
|
||||
auto writeResult =
|
||||
mServerSidePropStore->writeValue(std::move(updatedValue), /*updateStatus=*/true,
|
||||
VehiclePropertyStore::EventMode::ALWAYS);
|
||||
if (!writeResult.ok()) {
|
||||
return StatusError(getErrorCode(writeResult))
|
||||
<< "Failed to write value into property store, error: "
|
||||
<< getErrorMsg(writeResult);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<int32_t> FakeVehicleHardware::getSyncedAreaIdIfHvacDualOn(
|
||||
int32_t hvacTemperatureSetAreaId) const {
|
||||
auto hvacDualOnResults =
|
||||
mServerSidePropStore->readValuesForProperty(toInt(VehicleProperty::HVAC_DUAL_ON));
|
||||
if (!hvacDualOnResults.ok()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto& hvacDualOnValues = hvacDualOnResults.value();
|
||||
for (size_t i = 0; i < hvacDualOnValues.size(); i++) {
|
||||
if ((hvacDualOnValues[i]->areaId & hvacTemperatureSetAreaId) == hvacTemperatureSetAreaId &&
|
||||
hvacDualOnValues[i]->value.int32Values.size() == 1 &&
|
||||
hvacDualOnValues[i]->value.int32Values[0] == 1) {
|
||||
return hvacDualOnValues[i]->areaId;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getUserHalProp(
|
||||
const VehiclePropValue& value) const {
|
||||
auto propId = value.prop;
|
||||
@@ -853,6 +912,28 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu
|
||||
case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION):
|
||||
*isSpecialValue = true;
|
||||
return setHvacTemperatureValueSuggestion(value);
|
||||
case toInt(VehicleProperty::HVAC_TEMPERATURE_SET):
|
||||
if (value.value.floatValues.size() != 1) {
|
||||
*isSpecialValue = true;
|
||||
return StatusError(StatusCode::INVALID_ARG)
|
||||
<< "HVAC_DUAL_ON requires only one float value";
|
||||
}
|
||||
if (auto hvacDualOnAreaId = getSyncedAreaIdIfHvacDualOn(value.areaId);
|
||||
hvacDualOnAreaId.has_value()) {
|
||||
*isSpecialValue = true;
|
||||
return synchronizeHvacTemp(hvacDualOnAreaId.value(), value.value.floatValues[0]);
|
||||
}
|
||||
return {};
|
||||
case toInt(VehicleProperty::HVAC_DUAL_ON):
|
||||
if (value.value.int32Values.size() != 1) {
|
||||
*isSpecialValue = true;
|
||||
return StatusError(StatusCode::INVALID_ARG)
|
||||
<< "HVAC_DUAL_ON requires only one int32 value";
|
||||
}
|
||||
if (value.value.int32Values[0] == 1) {
|
||||
synchronizeHvacTemp(value.areaId, std::nullopt);
|
||||
}
|
||||
return {};
|
||||
case toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND): {
|
||||
isAdasPropertyAvailableResult =
|
||||
isAdasPropertyAvailable(toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE));
|
||||
|
||||
@@ -1889,6 +1889,101 @@ TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, testHvacDualOnSynchronizesTemp) {
|
||||
auto hvacDualOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_DUAL_ON)));
|
||||
auto hvacTemperatureSetConfig =
|
||||
std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
|
||||
EXPECT_NE(hvacDualOnConfig, nullptr);
|
||||
EXPECT_NE(hvacTemperatureSetConfig, nullptr);
|
||||
for (auto& hvacTemperatureSetConfig : hvacTemperatureSetConfig->areaConfigs) {
|
||||
int32_t hvacTemperatureSetAreaId = hvacTemperatureSetConfig.areaId;
|
||||
subscribe(toInt(VehicleProperty::HVAC_TEMPERATURE_SET), hvacTemperatureSetAreaId,
|
||||
/*sampleRateHz*/ 0);
|
||||
}
|
||||
for (auto& hvacDualOnConfig : hvacDualOnConfig->areaConfigs) {
|
||||
int32_t hvacDualOnAreaId = hvacDualOnConfig.areaId;
|
||||
subscribe(toInt(VehicleProperty::HVAC_DUAL_ON), hvacDualOnAreaId, /*sampleRateHz*/ 0);
|
||||
StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
|
||||
.areaId = hvacDualOnAreaId,
|
||||
.value.int32Values = {1}});
|
||||
EXPECT_EQ(status, StatusCode::OK);
|
||||
|
||||
// Verify there's an event for all HVAC_TEMPERATURE_SET
|
||||
// area IDs covered by the HVAC_DUAL_ON area ID
|
||||
auto events = getChangedProperties();
|
||||
std::unordered_set<float> temperatureValues;
|
||||
for (const auto& event : events) {
|
||||
// Ignore HVAC_DUAL_ON event
|
||||
if (event.prop == toInt(VehicleProperty::HVAC_DUAL_ON)) {
|
||||
continue;
|
||||
}
|
||||
EXPECT_EQ(event.prop, toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
EXPECT_EQ((hvacDualOnAreaId & event.areaId), event.areaId);
|
||||
EXPECT_EQ(1u, event.value.floatValues.size());
|
||||
temperatureValues.insert(event.value.floatValues[0]);
|
||||
}
|
||||
// Verify that the temperature value is the same for all events
|
||||
// Ie the temperature in all area IDs are synchronized
|
||||
EXPECT_EQ(1u, temperatureValues.size());
|
||||
clearChangedProperties();
|
||||
|
||||
// Verify when any HVAC_TEMPERATURE_SET area ID is changed all
|
||||
// area IDs covered by the HVAC_DUAL_ON area ID are also changed
|
||||
for (auto& hvacTemperatureSetConfig : hvacTemperatureSetConfig->areaConfigs) {
|
||||
int32_t hvacTemperatureSetAreaId = hvacTemperatureSetConfig.areaId;
|
||||
if ((hvacDualOnAreaId & hvacTemperatureSetAreaId) != hvacTemperatureSetAreaId) {
|
||||
continue;
|
||||
}
|
||||
float expectedValue = 25;
|
||||
status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
|
||||
.areaId = hvacTemperatureSetAreaId,
|
||||
.value.floatValues = {expectedValue}});
|
||||
EXPECT_EQ(status, StatusCode::OK);
|
||||
events = getChangedProperties();
|
||||
for (const auto& event : events) {
|
||||
EXPECT_EQ(event.prop, toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
EXPECT_EQ(1u, event.value.floatValues.size());
|
||||
EXPECT_EQ(expectedValue, event.value.floatValues[0]);
|
||||
}
|
||||
clearChangedProperties();
|
||||
}
|
||||
|
||||
status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
|
||||
.areaId = hvacDualOnAreaId,
|
||||
.value.int32Values = {0}});
|
||||
EXPECT_EQ(status, StatusCode::OK);
|
||||
|
||||
// When HVAC_DUAL_ON is disabled, there should be no events created
|
||||
// for HVAC_TEMPERATURE_SET ie no temperature synchronization.
|
||||
events = getChangedProperties();
|
||||
EXPECT_EQ(1u, events.size());
|
||||
EXPECT_EQ(events[0].prop, toInt(VehicleProperty::HVAC_DUAL_ON));
|
||||
EXPECT_EQ(events[0].areaId, hvacDualOnAreaId);
|
||||
clearChangedProperties();
|
||||
|
||||
// Verify when any HVAC_TEMPERATURE_SET area ID is
|
||||
// changed other area IDs do not change.
|
||||
for (auto& hvacTemperatureSetConfig : hvacTemperatureSetConfig->areaConfigs) {
|
||||
int32_t hvacTemperatureSetAreaId = hvacTemperatureSetConfig.areaId;
|
||||
if ((hvacDualOnAreaId & hvacTemperatureSetAreaId) != hvacTemperatureSetAreaId) {
|
||||
continue;
|
||||
}
|
||||
float expectedValue = 24;
|
||||
status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
|
||||
.areaId = hvacTemperatureSetAreaId,
|
||||
.value.floatValues = {expectedValue}});
|
||||
EXPECT_EQ(status, StatusCode::OK);
|
||||
events = getChangedProperties();
|
||||
EXPECT_EQ(1u, events.size());
|
||||
EXPECT_EQ(events[0].prop, toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
EXPECT_EQ(events[0].areaId, hvacTemperatureSetAreaId);
|
||||
EXPECT_EQ(1u, events[0].value.floatValues.size());
|
||||
EXPECT_EQ(expectedValue, events[0].value.floatValues[0]);
|
||||
clearChangedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, testGetAdasPropNotAvailable) {
|
||||
std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = {
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user