Refactor default values in VHAL

Move default values closer to config declration to add properties
with less pain in future.

Test: mm -j32; verified if Car Service works

(cherry picked from commit 24ade17518)
Merged-In: I2f18837658149eb657f44d81e34eb8e6e497a25c
Change-Id: Ie4285581fa9d871b366b0ed2f08fa8073739a0a9
This commit is contained in:
Pavel Maltsev 2017-03-29 12:09:54 -07:00
parent 33fd31e967
commit 8166677c4b
3 changed files with 246 additions and 273 deletions

View file

@ -33,176 +33,257 @@ const int32_t kHvacPowerProperties[] = {
toInt(VehicleProperty::HVAC_FAN_DIRECTION),
};
const VehiclePropConfig kVehicleProperties[] = {
struct ConfigDeclaration {
VehiclePropConfig config;
/* This value will be used as an initial value for the property. If this field is specified for
* property that supports multiple areas then it will be used for all areas unless particular
* area is overridden in initialAreaValue field. */
VehiclePropValue::RawValue initialValue;
/* Use initialAreaValues if it is necessary to specify different values per each area. */
std::map<int32_t, VehiclePropValue::RawValue> initialAreaValues;
};
const ConfigDeclaration kVehicleProperties[] {
{
.prop = toInt(VehicleProperty::INFO_MAKE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
.config = {
.prop = toInt(VehicleProperty::INFO_MAKE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
},
.initialValue = { .stringValue = "Toy Vehicle" }
},
{
.config = {
.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = {0} }
},
{
.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.config = {
.prop = toInt(VehicleProperty::CURRENT_GEAR),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } }
},
{
.prop = toInt(VehicleProperty::CURRENT_GEAR),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.config = {
.prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = {1} }
},
{
.prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.config = {
.prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = {0} }
},
{
.prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.config = {
.prop = toInt(VehicleProperty::HVAC_POWER_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
// TODO(bryaneyler): Ideally, this is generated dynamically from
// kHvacPowerProperties.
.configString = "0x12400500,0x12400501" // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION
},
.initialValue = { .int32Values = {1} }
},
{
.prop = toInt(VehicleProperty::HVAC_POWER_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
// TODO(bryaneyler): Ideally, this is generated dynamically from
// kHvacPowerProperties.
.configString = "0x12400500,0x12400501" // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION
.config = {
.prop = toInt(VehicleProperty::HVAC_DEFROSTER),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas =
VehicleAreaWindow::FRONT_WINDSHIELD
| VehicleAreaWindow::REAR_WINDSHIELD
},
.initialValue = { .int32Values = {0} } // Will be used for all areas.
},
{
.prop = toInt(VehicleProperty::HVAC_DEFROSTER),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas =
VehicleAreaWindow::FRONT_WINDSHIELD
| VehicleAreaWindow::REAR_WINDSHIELD
.config = {
.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
.initialValue = { .int32Values = {1} }
},
{
.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
.config = {
.prop = toInt(VehicleProperty::HVAC_AC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
.initialValue = { .int32Values = {1} }
},
{
.prop = toInt(VehicleProperty::HVAC_AC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
.config = {
.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
.initialValue = { .int32Values = {1} }
},
{
.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
.config = {
.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
.areaConfigs = {
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1),
.minInt32Value = 1,
.maxInt32Value = 7
}
}
},
.initialValue = { .int32Values = {3} }
},
{
.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
.areaConfigs = {
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1),
.minInt32Value = 1,
.maxInt32Value = 7
.config = {
.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
},
.initialValue = { .int32Values = { toInt(VehicleHvacFanDirection::FACE) } }
},
{
.config = {
.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas =
VehicleAreaZone::ROW_1_LEFT
| VehicleAreaZone::ROW_1_RIGHT,
.areaConfigs = {
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
.minFloatValue = 16,
.maxFloatValue = 32,
},
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
.minFloatValue = 16,
.maxFloatValue = 32,
}
}
},
.initialAreaValues = {
{
toInt(VehicleAreaZone::ROW_1_LEFT),
{ .int32Values = {16} }
}, {
toInt(VehicleAreaZone::ROW_1_RIGHT),
{.int32Values = {20} }
}
}
},
{
.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
.config = {
.prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
.access = VehiclePropertyAccess::READ,
// TODO(bryaneyler): Support ON_CHANGE as well.
.changeMode = VehiclePropertyChangeMode::CONTINUOUS,
.minSampleRate = 1.0f,
.maxSampleRate = 2.0f,
},
.initialValue = { .int32Values = {25} }
},
{
.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.supportedAreas =
VehicleAreaZone::ROW_1_LEFT
| VehicleAreaZone::ROW_1_RIGHT,
.areaConfigs = {
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
.minFloatValue = 16,
.maxFloatValue = 32,
},
VehicleAreaConfig {
.areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
.minFloatValue = 16,
.maxFloatValue = 32,
.config = {
.prop = toInt(VehicleProperty::NIGHT_MODE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = {0} }
},
{
.config = {
.prop = toInt(VehicleProperty::DRIVING_STATUS),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = { toInt(VehicleDrivingStatus::UNRESTRICTED) } }
},
{
.config = {
.prop = toInt(VehicleProperty::GEAR_SELECTION),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } }
},
{
.config = {
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
},
.initialValue = { .floatValues = { 123000.0f } } // In Milliliters
},
{
.config = {
.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.areaConfigs = {
VehicleAreaConfig {
.minInt32Value = 0,
.maxInt32Value = 10
}
}
}
},
.initialValue = { .int32Values = {7} }
},
{
.prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
.access = VehiclePropertyAccess::READ,
// TODO(bryaneyler): Support ON_CHANGE as well.
.changeMode = VehiclePropertyChangeMode::CONTINUOUS,
.minSampleRate = 1.0f,
.maxSampleRate = 2.0f,
.config = {
.prop = toInt(VehicleProperty::IGNITION_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = { .int32Values = { toInt(VehicleIgnitionState::ON) } }
},
{
.prop = toInt(VehicleProperty::NIGHT_MODE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
{
.prop = toInt(VehicleProperty::DRIVING_STATUS),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
{
.prop = toInt(VehicleProperty::GEAR_SELECTION),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
{
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
},
{
.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.areaConfigs = {
VehicleAreaConfig {
.minInt32Value = 0,
.maxInt32Value = 10
}
}
},
{
.prop = toInt(VehicleProperty::IGNITION_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
{
.prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::CONTINUOUS,
.minSampleRate = 0.1, // 0.1 Hz, every 10 seconds
.maxSampleRate = 10, // 10 Hz, every 100 ms
.config = {
.prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::CONTINUOUS,
.minSampleRate = 0.1, // 0.1 Hz, every 10 seconds
.maxSampleRate = 10, // 10 Hz, every 100 ms
},
.initialValue = { .floatValues = {101.0f} }
}
};

View file

@ -353,80 +353,6 @@ void DefaultVehicleHal::rxThread() {
}
}
// This function sets the default value of a property if we are interested in setting it.
// TODO: Co-locate the default values with the configuration structure, to make it easier to
// add new properties and their defaults.
void DefaultVehicleHal::setDefaultValue(VehiclePropValue* prop) {
switch (prop->prop) {
case toInt(VehicleProperty::INFO_MAKE):
prop->value.stringValue = "Default Car";
break;
case toInt(VehicleProperty::PERF_VEHICLE_SPEED):
prop->value.floatValues[0] = 0;
break;
case toInt(VehicleProperty::CURRENT_GEAR):
prop->value.int32Values[0] = toInt(VehicleGear::GEAR_PARK);
break;
case toInt(VehicleProperty::PARKING_BRAKE_ON):
prop->value.int32Values[0] = 1;
break;
case toInt(VehicleProperty::FUEL_LEVEL_LOW):
prop->value.int32Values[0] = 0;
break;
case toInt(VehicleProperty::HVAC_POWER_ON):
prop->value.int32Values[0] = 1;
break;
case toInt(VehicleProperty::HVAC_DEFROSTER):
prop->value.int32Values[0] = 0;
break;
case toInt(VehicleProperty::HVAC_RECIRC_ON):
prop->value.int32Values[0] = 1;
break;
case toInt(VehicleProperty::HVAC_AC_ON):
prop->value.int32Values[0] = 1;
break;
case toInt(VehicleProperty::HVAC_AUTO_ON):
prop->value.int32Values[0] = 1;
break;
case toInt(VehicleProperty::HVAC_FAN_SPEED):
prop->value.int32Values[0] = 3;
break;
case toInt(VehicleProperty::HVAC_FAN_DIRECTION):
prop->value.int32Values[0] = toInt(VehicleHvacFanDirection::FACE);
break;
case toInt(VehicleProperty::HVAC_TEMPERATURE_SET):
prop->value.floatValues[0] = 16;
break;
case toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE):
prop->value.floatValues[0] = 25;
break;
case toInt(VehicleProperty::NIGHT_MODE):
prop->value.int32Values[0] = 0;
break;
case toInt(VehicleProperty::DRIVING_STATUS):
prop->value.int32Values[0] = toInt(VehicleDrivingStatus::UNRESTRICTED);
break;
case toInt(VehicleProperty::GEAR_SELECTION):
prop->value.int32Values[0] = toInt(VehicleGear::GEAR_PARK);
break;
case toInt(VehicleProperty::INFO_FUEL_CAPACITY):
prop->value.floatValues[0] = 123000.0f; // In milliliters
break;
case toInt(VehicleProperty::ENGINE_OIL_TEMP):
prop->value.floatValues[0] = 101;
break;
case toInt(VehicleProperty::DISPLAY_BRIGHTNESS):
prop->value.int32Values[0] = 7;
break;
case toInt(VehicleProperty::IGNITION_STATE):
prop->value.int32Values[0] = toInt(VehicleIgnitionState::ON);
break;
default:
ALOGW("%s: propId=0x%x not found", __func__, prop->prop);
break;
}
}
// Transmit a reply back to the emulator
void DefaultVehicleHal::txMsg(emulator::EmulatorMessage& txMsg) {
int numBytes = txMsg.ByteSize();
@ -546,44 +472,9 @@ void DefaultVehicleHal::onCreate() {
mHvacPowerProps.insert(prop);
}
// Get the list of configurations supported by this HAL
std::vector<VehiclePropConfig> configs = listProperties();
for (auto& cfg : configs) {
VehiclePropertyType propType = getPropType(cfg.prop);
for (auto& it : kVehicleProperties) {
VehiclePropConfig cfg = it.config;
int32_t supportedAreas = cfg.supportedAreas;
int32_t vecSize;
// Set the vector size based on property type
switch (propType) {
case VehiclePropertyType::BOOLEAN:
case VehiclePropertyType::INT32:
case VehiclePropertyType::INT64:
case VehiclePropertyType::FLOAT:
vecSize = 1;
break;
case VehiclePropertyType::INT32_VEC:
case VehiclePropertyType::FLOAT_VEC:
case VehiclePropertyType::BYTES:
// TODO: Add proper support for these types
vecSize = 1;
break;
case VehiclePropertyType::STRING:
// Require individual handling
vecSize = 0;
break;
case VehiclePropertyType::COMPLEX:
switch (cfg.prop) {
default:
// Need to handle each complex property separately
break;
}
continue;
default:
ALOGE("%s: propType=0x%x not found", __func__, propType);
vecSize = 0;
break;
}
// A global property will have supportedAreas = 0
if (getPropArea(cfg.prop) == VehicleArea::GLOBAL) {
@ -593,23 +484,29 @@ void DefaultVehicleHal::onCreate() {
// This loop is a do-while so it executes at least once to handle global properties
do {
int32_t curArea = supportedAreas;
// Clear the right-most bit of supportedAreas
supportedAreas &= supportedAreas - 1;
// Set curArea to the previously cleared bit
curArea ^= supportedAreas;
supportedAreas &= supportedAreas - 1; // Clear the right-most bit of supportedAreas.
curArea ^= supportedAreas; // Set curArea to the previously cleared bit.
// Create a separate instance for each individual zone
std::unique_ptr<VehiclePropValue> prop = createVehiclePropValue(propType, vecSize);
prop->areaId = curArea;
prop->prop = cfg.prop;
setDefaultValue(prop.get());
std::unique_ptr<CustomVehiclePropertyHandler> handler;
handler.reset(new StoredValueCustomVehiclePropertyHandler());
handler->set(*prop);
mProps[std::make_pair(prop->prop, prop->areaId)] =
std::move(handler);
VehiclePropValue prop = {
.prop = cfg.prop,
.areaId = curArea,
};
if (it.initialAreaValues.size() > 0) {
auto valueForAreaIt = it.initialAreaValues.find(curArea);
if (valueForAreaIt != it.initialAreaValues.end()) {
prop.value = valueForAreaIt->second;
} else {
ALOGW("%s failed to get default value for prop 0x%x area 0x%x",
__func__, cfg.prop, curArea);
}
} else {
prop.value = it.initialValue;
}
auto handler = std::make_unique<StoredValueCustomVehiclePropertyHandler>();
handler->set(prop);
mProps[std::make_pair(prop.prop, prop.areaId)] = std::move(handler);
} while (supportedAreas != 0);
}
@ -617,6 +514,14 @@ void DefaultVehicleHal::onCreate() {
mThread = std::thread(&DefaultVehicleHal::rxThread, this);
}
std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() {
std::vector<VehiclePropConfig> configs(mPropConfigMap.size());
for (auto&& it : mPropConfigMap) {
configs.push_back(*it.second);
}
return configs;
}
void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
VehiclePropValuePtr v;

View file

@ -71,7 +71,8 @@ public:
DefaultVehicleHal() : mRecurrentTimer(
std::bind(&DefaultVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)) {
for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
mPropConfigMap[kVehicleProperties[i].prop] = &kVehicleProperties[i];
const auto* config = &kVehicleProperties[i].config;
mPropConfigMap[config->prop] = config;
}
}
@ -85,20 +86,12 @@ public:
mThread.join();
}
std::vector<VehiclePropConfig> listProperties() override {
return std::vector<VehiclePropConfig>(std::begin(kVehicleProperties),
std::end(kVehicleProperties));
}
void onCreate() override;
std::vector<VehiclePropConfig> listProperties() override;
VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
StatusCode* outStatus) override;
void onCreate() override;
StatusCode set(const VehiclePropValue& propValue) override;
StatusCode subscribe(int32_t property, int32_t areas, float sampleRate) override;
StatusCode unsubscribe(int32_t property) override;
/**
@ -125,17 +118,12 @@ public:
* this value at will
* @return OK on success, an error code on failure
*/
virtual StatusCode addCustomProperty(
const VehiclePropValue& initialValue) {
std::unique_ptr<CustomVehiclePropertyHandler> handler;
handler.reset(new StoredValueCustomVehiclePropertyHandler());
StatusCode setResponse = handler->set(initialValue);
if (StatusCode::OK == setResponse) {
return addCustomProperty(initialValue.prop,
std::move(handler));
} else {
return setResponse;
}
virtual StatusCode addCustomProperty(const VehiclePropValue& initialValue) {
auto handler = std::make_unique<StoredValueCustomVehiclePropertyHandler>();
StatusCode response = handler->set(initialValue);
return StatusCode::OK == response
? addCustomProperty(initialValue.prop, std::move(handler))
: response;
}
private:
@ -152,7 +140,6 @@ private:
const VehiclePropConfig& cfg);
void populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
const VehiclePropValue* val);
void setDefaultValue(VehiclePropValue* prop);
void rxMsg();
void rxThread();
void txMsg(emulator::EmulatorMessage& txMsg);