Make HVAC dep properties unavailable to get when power is off.
Previously HVAC properties are unavailable to set when hvac power is
off. This CL makes VHAL returns NOT_AVAILABLE for get as well. VHAL
will also generate property change event when the power is switched
on again.
Test: atest FakeVehicleHardwareTest
Bug: 262461830
Change-Id: I17ca8a4e48f3ff5854226a6a38a42220078073d5
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 e515bad..eac1ffa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -194,7 +194,7 @@
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
ValueResultType getEchoReverseBytes(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
- bool isHvacPropAndHvacNotAvailable(int32_t propId);
+ bool isHvacPropAndHvacNotAvailable(int32_t propId) const;
std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
@@ -236,6 +236,7 @@
const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);
std::string genFakeDataCommand(const std::vector<std::string>& options);
+ void sendHvacPropertiesCurrentValues();
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
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 dd76524..4115c11 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -295,7 +295,7 @@
return {};
}
-bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
+bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) const {
std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
std::end(HVAC_POWER_PROPERTIES));
if (powerProps.count(propId)) {
@@ -366,6 +366,11 @@
return getUserHalProp(value);
}
+ if (isHvacPropAndHvacNotAvailable(propId)) {
+ *isSpecialValue = true;
+ return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
+ }
+
switch (propId) {
case OBD2_FREEZE_FRAME:
*isSpecialValue = true;
@@ -408,6 +413,27 @@
return std::move(gotValue);
}
+void FakeVehicleHardware::sendHvacPropertiesCurrentValues() {
+ for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+ int powerPropId = HVAC_POWER_PROPERTIES[i];
+ auto powerPropResults = mServerSidePropStore->readValuesForProperty(powerPropId);
+ if (!powerPropResults.ok()) {
+ ALOGW("failed to get power prop 0x%x, error: %s", powerPropId,
+ getErrorMsg(powerPropResults).c_str());
+ continue;
+ }
+ auto& powerPropValues = powerPropResults.value();
+ for (size_t j = 0; j < powerPropValues.size(); j++) {
+ auto powerPropValue = std::move(powerPropValues[j]);
+ powerPropValue->status = VehiclePropertyStatus::AVAILABLE;
+ powerPropValue->timestamp = elapsedRealtimeNano();
+ // This will trigger a property change event for the current hvac property value.
+ mServerSidePropStore->writeValue(std::move(powerPropValue), /*updateStatus=*/true,
+ VehiclePropertyStore::EventMode::ALWAYS);
+ }
+ }
+}
+
VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
bool* isSpecialValue) {
*isSpecialValue = false;
@@ -419,6 +445,13 @@
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();
+ }
+
if (isHvacPropAndHvacNotAvailable(propId)) {
*isSpecialValue = true;
return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
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 0184462..08de312 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -61,6 +61,7 @@
using ::android::base::ScopedLockAssertion;
using ::android::base::StringPrintf;
using ::android::base::unexpected;
+using ::testing::AnyOfArray;
using ::testing::ContainerEq;
using ::testing::ContainsRegex;
using ::testing::Eq;
@@ -1140,6 +1141,71 @@
EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
}
+TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = HVAC_ALL,
+ .value.int32Values = {0}});
+
+ 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];
+ auto getValueResult = getValue(VehiclePropValue{
+ .prop = powerPropId,
+ .areaId = HVAC_ALL,
+ });
+
+ EXPECT_FALSE(getValueResult.ok());
+ EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
+ }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = HVAC_ALL,
+ .value.int32Values = {0}});
+
+ 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];
+ status = setValue(VehiclePropValue{
+ .prop = powerPropId,
+ .areaId = HVAC_ALL,
+ });
+
+ EXPECT_EQ(status, StatusCode::NOT_AVAILABLE);
+ }
+}
+
+TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = HVAC_ALL,
+ .value.int32Values = {0}});
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ clearChangedProperties();
+
+ status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = HVAC_ALL,
+ .value.int32Values = {1}});
+
+ 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]);
+ }
+ changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON));
+ ASSERT_EQ(events.size(), changedPropIds.size());
+ for (const auto& event : events) {
+ EXPECT_EQ(event.areaId, HVAC_ALL);
+ EXPECT_THAT(event.prop, AnyOfArray(changedPropIds));
+ }
+}
+
TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
for (VehicleProperty prop : std::vector<VehicleProperty>({
VehicleProperty::INITIAL_USER_INFO,