Implement ADAS properties in emulator VHAL

For properties that support the ErrorState enum, they are set to
ErrorState#NOT_AVAILABLE_DISABLED when the ADAS feature is disabled.
For all the other ADAS properties, they return
StatusCode#NOT_AVAILABLE_DISABLED when that ADAS feature is disabled.

Bug: 277359330
Bug: 277359630
Bug: 277359374
Bug: 277359394
Bug: 277359419
Bug: 277359421
Bug: 277359396
Bug: 277359260

Test: atest FakeVehicleHardwareTest
Test: atest CtsCarTestCases:CarPropertyManagerTest
Change-Id: I11386cbaa320038001c650a63cc70f6ca6498c09
This commit is contained in:
Aaqib Ismail
2023-04-12 11:51:39 -07:00
parent cee699a37b
commit a089c8ed53
3 changed files with 816 additions and 1 deletions

View File

@@ -195,6 +195,8 @@ class FakeVehicleHardware : public IVehicleHardware {
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
VehiclePropValuePool::RecyclableType createApPowerStateReq(
aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state);
VehiclePropValuePool::RecyclableType createAdasStateReq(int32_t propertyId, int32_t areaId,
int32_t state);
VhalResult<void> setUserHalProp(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
ValueResultType getUserHalProp(
@@ -202,6 +204,7 @@ class FakeVehicleHardware : public IVehicleHardware {
ValueResultType getEchoReverseBytes(
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;
std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
@@ -244,6 +247,7 @@ class FakeVehicleHardware : public IVehicleHardware {
std::string genFakeDataCommand(const std::vector<std::string>& options);
void sendHvacPropertiesCurrentValues(int32_t areaId);
void sendAdasPropertiesState(int32_t propertyId, int32_t state);
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,

View File

@@ -52,6 +52,7 @@ namespace fake {
namespace {
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
@@ -107,6 +108,74 @@ const std::unordered_set<std::string> SET_PROP_OPTIONS = {
// Timestamp in int64.
"-t"};
// ADAS _ENABLED property to list of ADAS state properties using ErrorState enum.
const std::unordered_map<int32_t, std::vector<int32_t>> mAdasEnabledPropToAdasPropWithErrorState = {
// AEB
{
toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
{
toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE),
},
},
// FCW
{
toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED),
{
toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE),
},
},
// BSW
{
toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
{
toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE),
},
},
// LDW
{
toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED),
{
toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
},
},
// LKA
{
toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
{
toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
},
},
// LCA
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE),
},
},
// ELKA
{
toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
{
toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE),
},
},
// CC
{
toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
{
toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
toInt(VehicleProperty::CRUISE_CONTROL_STATE),
},
},
// HOD
{
toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED),
{
toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE),
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
};
} // namespace
void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
@@ -238,6 +307,18 @@ VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq(
return req;
}
VehiclePropValuePool::RecyclableType FakeVehicleHardware::createAdasStateReq(int32_t propertyId,
int32_t areaId,
int32_t state) {
auto req = mValuePool->obtain(VehiclePropertyType::INT32);
req->prop = propertyId;
req->areaId = areaId;
req->timestamp = elapsedRealtimeNano();
req->status = VehiclePropertyStatus::AVAILABLE;
req->value.int32Values[0] = state;
return req;
}
VhalResult<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
auto updatedValue = mValuePool->obtain(value);
updatedValue->timestamp = elapsedRealtimeNano();
@@ -413,6 +494,41 @@ bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t
return false;
}
VhalResult<void> FakeVehicleHardware::isAdasPropertyAvailable(int32_t adasStatePropertyId) const {
auto adasStateResult = mServerSidePropStore->readValue(adasStatePropertyId);
if (!adasStateResult.ok()) {
ALOGW("Failed to get ADAS ENABLED property 0x%x, error: %s", adasStatePropertyId,
getErrorMsg(adasStateResult).c_str());
return {};
}
if (adasStateResult.value()->value.int32Values.size() == 1 &&
adasStateResult.value()->value.int32Values[0] < 0) {
auto errorState = adasStateResult.value()->value.int32Values[0];
switch (errorState) {
case toInt(ErrorState::NOT_AVAILABLE_DISABLED):
return StatusError(StatusCode::NOT_AVAILABLE_DISABLED)
<< "ADAS feature is disabled.";
case toInt(ErrorState::NOT_AVAILABLE_SPEED_LOW):
return StatusError(StatusCode::NOT_AVAILABLE_SPEED_LOW)
<< "ADAS feature is disabled because the vehicle speed is too low.";
case toInt(ErrorState::NOT_AVAILABLE_SPEED_HIGH):
return StatusError(StatusCode::NOT_AVAILABLE_SPEED_HIGH)
<< "ADAS feature is disabled because the vehicle speed is too high.";
case toInt(ErrorState::NOT_AVAILABLE_POOR_VISIBILITY):
return StatusError(StatusCode::NOT_AVAILABLE_POOR_VISIBILITY)
<< "ADAS feature is disabled because the visibility is too poor.";
case toInt(ErrorState::NOT_AVAILABLE_SAFETY):
return StatusError(StatusCode::NOT_AVAILABLE_SAFETY)
<< "ADAS feature is disabled because of safety reasons.";
default:
return StatusError(StatusCode::NOT_AVAILABLE) << "ADAS feature is not available.";
}
}
return {};
}
VhalResult<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& value) {
auto result = mFakeUserHal->onSetProperty(value);
if (!result.ok()) {
@@ -495,6 +611,19 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue(
case VENDOR_PROPERTY_ID:
*isSpecialValue = true;
return StatusError((StatusCode)VENDOR_ERROR_CODE);
case toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED):
[[fallthrough]];
case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP):
[[fallthrough]];
case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE): {
auto isAdasPropertyAvailableResult =
isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE));
if (!isAdasPropertyAvailableResult.ok()) {
*isSpecialValue = true;
return isAdasPropertyAvailableResult.error();
}
return nullptr;
}
default:
// Do nothing.
break;
@@ -542,6 +671,25 @@ void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) {
}
}
void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) {
auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second;
for (auto dependentPropId : adasDependentPropIds) {
auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId);
if (!dependentPropConfigResult.ok()) {
ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId,
getErrorMsg(dependentPropConfigResult).c_str());
continue;
}
auto& dependentPropConfig = dependentPropConfigResult.value();
for (auto& areaConfig : dependentPropConfig->areaConfigs) {
auto propValue = createAdasStateReq(dependentPropId, areaConfig.areaId, state);
// This will trigger a property change event for the current ADAS property value.
mServerSidePropStore->writeValue(std::move(propValue), /*updateStatus=*/true,
VehiclePropertyStore::EventMode::ALWAYS);
}
}
}
VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
bool* isSpecialValue) {
*isSpecialValue = false;
@@ -565,6 +713,16 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu
return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) << "hvac not available";
}
if (mAdasEnabledPropToAdasPropWithErrorState.count(propId) &&
value.value.int32Values.size() == 1) {
if (value.value.int32Values[0] == 1) {
// Set default state to 1 when ADAS feature is enabled.
sendAdasPropertiesState(propId, /* state = */ 1);
} else {
sendAdasPropertiesState(propId, toInt(ErrorState::NOT_AVAILABLE_DISABLED));
}
}
switch (propId) {
case toInt(VehicleProperty::AP_POWER_STATE_REPORT):
*isSpecialValue = true;
@@ -583,6 +741,24 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu
case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION):
*isSpecialValue = true;
return setHvacTemperatureValueSuggestion(value);
case toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND): {
auto isAdasPropertyAvailableResult =
isAdasPropertyAvailable(toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE));
if (!isAdasPropertyAvailableResult.ok()) {
*isSpecialValue = true;
}
return isAdasPropertyAvailableResult;
}
case toInt(VehicleProperty::CRUISE_CONTROL_COMMAND):
[[fallthrough]];
case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP): {
auto isAdasPropertyAvailableResult =
isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE));
if (!isAdasPropertyAvailableResult.ok()) {
*isSpecialValue = true;
}
return isAdasPropertyAvailableResult;
}
#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
case toInt(VehicleProperty::CLUSTER_REPORT_STATE):

View File

@@ -60,6 +60,7 @@ namespace vehicle {
namespace fake {
namespace {
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
@@ -68,6 +69,7 @@ using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
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;
@@ -1035,6 +1037,488 @@ std::vector<SetSpecialValueTestCase> setSpecialValueTestCases() {
},
},
},
SetSpecialValueTestCase{
.name = "set_automatic_emergency_braking_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_automatic_emergency_braking_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::
AUTOMATIC_EMERGENCY_BRAKING_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_forward_collision_warning_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
FORWARD_COLLISION_WARNING_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
FORWARD_COLLISION_WARNING_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
FORWARD_COLLISION_WARNING_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_forward_collision_warning_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
FORWARD_COLLISION_WARNING_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
FORWARD_COLLISION_WARNING_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
FORWARD_COLLISION_WARNING_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_blind_spot_warning_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_STATE),
.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_STATE),
.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_blind_spot_warning_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_STATE),
.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::BLIND_SPOT_WARNING_STATE),
.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_departure_warning_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::
LANE_DEPARTURE_WARNING_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::
LANE_DEPARTURE_WARNING_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_departure_warning_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::
LANE_DEPARTURE_WARNING_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::
LANE_DEPARTURE_WARNING_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_keep_assist_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_keep_assist_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_centering_assist_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_lane_centering_assist_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::LANE_CENTERING_ASSIST_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_emergency_lane_keep_assist_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_emergency_lane_keep_assist_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
EMERGENCY_LANE_KEEP_ASSIST_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_cruise_control_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_cruise_control_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE),
.value.int32Values = {1},
},
},
},
SetSpecialValueTestCase{
.name = "set_hands_on_detection_enabled_false",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_ENABLED),
.value.int32Values = {0},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_ENABLED),
.value.int32Values = {0},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
HANDS_ON_DETECTION_DRIVER_STATE),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_WARNING),
.value.int32Values = {toInt(
ErrorState::NOT_AVAILABLE_DISABLED)},
},
},
},
SetSpecialValueTestCase{
.name = "set_hands_on_detection_enabled_true",
.valuesToSet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_ENABLED),
.value.int32Values = {1},
},
},
.expectedValuesToGet =
{
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_ENABLED),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(VehicleProperty::
HANDS_ON_DETECTION_DRIVER_STATE),
.value.int32Values = {1},
},
VehiclePropValue{
.prop = toInt(
VehicleProperty::HANDS_ON_DETECTION_WARNING),
.value.int32Values = {1},
},
},
},
};
}
@@ -1052,7 +1536,7 @@ TEST_P(FakeVehicleHardwareSpecialValuesTest, testSetSpecialProperties) {
std::vector<VehiclePropValue> gotValues;
for (const auto& value : tc.expectedValuesToGet) {
auto result = getValue(VehiclePropValue{.prop = value.prop});
auto result = getValue(VehiclePropValue{.prop = value.prop, .areaId = value.areaId});
ASSERT_TRUE(result.ok()) << "failed to get property " << value.prop
<< " status:" << getStatus(result);
@@ -1263,6 +1747,157 @@ TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
}
}
TEST_F(FakeVehicleHardwareTest, testGetAdasPropNotAvailable) {
std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = {
{
toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
{
toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED),
toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP),
toInt(VehicleProperty::
ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE),
},
},
};
for (auto& enabledToDependents : adasEnabledPropToDependentProps) {
int32_t adasEnabledPropertyId = enabledToDependents.first;
StatusCode status =
setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
EXPECT_EQ(status, StatusCode::OK);
auto& dependentProps = enabledToDependents.second;
for (auto dependentProp : dependentProps) {
auto getValueResult = getValue(VehiclePropValue{.prop = dependentProp});
EXPECT_FALSE(getValueResult.ok());
EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE_DISABLED);
}
}
}
TEST_F(FakeVehicleHardwareTest, testSetAdasPropNotAvailable) {
std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = {
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND),
},
},
{
toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
{
toInt(VehicleProperty::CRUISE_CONTROL_COMMAND),
toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP),
},
},
};
for (auto& enabledToDependents : adasEnabledPropToDependentProps) {
int32_t adasEnabledPropertyId = enabledToDependents.first;
StatusCode status =
setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
EXPECT_EQ(status, StatusCode::OK);
auto& dependentProps = enabledToDependents.second;
for (auto dependentProp : dependentProps) {
StatusCode status = setValue(VehiclePropValue{.prop = dependentProp});
EXPECT_EQ(status, StatusCode::NOT_AVAILABLE_DISABLED);
}
}
}
TEST_F(FakeVehicleHardwareTest, testSendAdasPropertiesState) {
std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToAdasPropWithErrorState = {
// AEB
{
toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
{
toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE),
},
},
// FCW
{
toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED),
{
toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE),
},
},
// BSW
{
toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
{
toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE),
},
},
// LDW
{
toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED),
{
toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
},
},
// LKA
{
toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
{
toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
},
},
// LCA
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
{
toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE),
},
},
// ELKA
{
toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
{
toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE),
},
},
// CC
{
toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
{
toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
toInt(VehicleProperty::CRUISE_CONTROL_STATE),
},
},
// HOD
{
toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED),
{
toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE),
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
};
for (auto& enabledToErrorStateProps : adasEnabledPropToAdasPropWithErrorState) {
int32_t adasEnabledPropertyId = enabledToErrorStateProps.first;
StatusCode status =
setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
EXPECT_EQ(status, StatusCode::OK);
clearChangedProperties();
status =
setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {1}});
EXPECT_EQ(status, StatusCode::OK);
// If we enable the ADAS feature, we expect to receive one property event for every ADAS
// state property plus one event for enabling the feature.
std::unordered_set<int32_t> expectedChangedPropIds(enabledToErrorStateProps.second.begin(),
enabledToErrorStateProps.second.end());
expectedChangedPropIds.insert(adasEnabledPropertyId);
std::unordered_set<int32_t> changedPropIds;
auto events = getChangedProperties();
for (const auto& event : events) {
changedPropIds.insert(event.prop);
}
EXPECT_EQ(changedPropIds, expectedChangedPropIds);
}
}
TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
for (VehicleProperty prop : std::vector<VehicleProperty>({
VehicleProperty::INITIAL_USER_INFO,