Loading automotive/vehicle/2.0/default/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \ common/src/SubscriptionManager.cpp \ common/src/VehicleHalManager.cpp \ common/src/VehicleObjectPool.cpp \ common/src/VehiclePropertyStore.cpp \ common/src/VehicleUtils.cpp \ LOCAL_C_INCLUDES := \ Loading Loading @@ -72,9 +73,10 @@ include $(CLEAR_VARS) LOCAL_MODULE:= $(vhal_v2_0)-default-impl-lib LOCAL_SRC_FILES:= \ impl/vhal_v2_0/DefaultVehicleHal.cpp \ impl/vhal_v2_0/EmulatedVehicleHal.cpp \ impl/vhal_v2_0/VehicleEmulator.cpp \ impl/vhal_v2_0/PipeComm.cpp \ impl/vhal_v2_0/SocketComm.cpp impl/vhal_v2_0/SocketComm.cpp \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/impl/vhal_v2_0 Loading automotive/vehicle/2.0/default/VehicleService.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -21,14 +21,16 @@ #include <iostream> #include <vhal_v2_0/VehicleHalManager.h> #include <vhal_v2_0/DefaultVehicleHal.h> #include <vhal_v2_0/EmulatedVehicleHal.h> using namespace android; using namespace android::hardware; using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto hal = std::make_unique<impl::DefaultVehicleHal>(); auto store = std::make_unique<VehiclePropertyStore>(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get()); auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get()); auto service = std::make_unique<VehicleHalManager>(hal.get()); configureRpcThreadpool(1, true /* callerWillJoin */); Loading automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h 0 → 100644 +104 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_ #define android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_ #include <cstdint> #include <unordered_map> #include <memory> #include <mutex> #include <android/hardware/automotive/vehicle/2.0/IVehicle.h> namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace V2_0 { /** * Encapsulates work related to storing and accessing configuration, storing and modifying * vehicle property values. * * VehiclePropertyValues stored in a sorted map thus it makes easier to get range of values, e.g. * to get value for all areas for particular property. * * This class is thread-safe, however it uses blocking synchronization across all methods. */ class VehiclePropertyStore { public: /* Function that used to calculate unique token for given VehiclePropValue */ using TokenFunction = std::function<int64_t(const VehiclePropValue& value)>; private: struct RecordConfig { VehiclePropConfig propConfig; TokenFunction tokenFunction; }; struct RecordId { int32_t prop; int32_t area; int64_t token; bool operator==(const RecordId& other) const; bool operator<(const RecordId& other) const; }; using PropertyMap = std::map<RecordId, VehiclePropValue>; using PropertyMapRange = std::pair<PropertyMap::const_iterator, PropertyMap::const_iterator>; public: void registerProperty(const VehiclePropConfig& config, TokenFunction tokenFunc = nullptr); /* Stores provided value. Returns true if value was written returns false if config for * example wasn't registered. */ bool writeValue(const VehiclePropValue& propValue); void removeValue(const VehiclePropValue& propValue); void removeValuesForProperty(int32_t propId); std::vector<VehiclePropValue> readAllValues() const; std::vector<VehiclePropValue> readValuesForProperty(int32_t propId) const; std::unique_ptr<VehiclePropValue> readValueOrNull(const VehiclePropValue& request) const; std::unique_ptr<VehiclePropValue> readValueOrNull(int32_t prop, int32_t area = 0, int64_t token = 0) const; std::vector<VehiclePropConfig> getAllConfigs() const; const VehiclePropConfig* getConfigOrNull(int32_t propId) const; const VehiclePropConfig* getConfigOrDie(int32_t propId) const; private: RecordId getRecordIdLocked(const VehiclePropValue& valuePrototype) const; const VehiclePropValue* getValueOrNullLocked(const RecordId& recId) const; PropertyMapRange findRangeLocked(int32_t propId) const; private: using MuxGuard = std::lock_guard<std::mutex>; mutable std::mutex mLock; std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs; PropertyMap mPropertyValues; // Sorted map of RecordId : VehiclePropValue. }; } // namespace V2_0 } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android #endif //android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_ automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VehiclePropertyStore" #include <android/log.h> #include <common/include/vhal_v2_0/VehicleUtils.h> #include "VehiclePropertyStore.h" namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace V2_0 { bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const { return prop == other.prop && area == other.area && token == other.token; } bool VehiclePropertyStore::RecordId::operator<(const VehiclePropertyStore::RecordId& other) const { return prop < other.prop || (prop == other.prop && area < other.area) || (prop == other.prop && area == other.area && token < other.token); } void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config, VehiclePropertyStore::TokenFunction tokenFunc) { MuxGuard g(mLock); mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } }); } bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue) { MuxGuard g(mLock); if (!mConfigs.count(propValue.prop)) return false; RecordId recId = getRecordIdLocked(propValue); VehiclePropValue* valueToUpdate = const_cast<VehiclePropValue*>(getValueOrNullLocked(recId)); if (valueToUpdate == nullptr) { mPropertyValues.insert({ recId, propValue }); } else { valueToUpdate->timestamp = propValue.timestamp; valueToUpdate->value = propValue.value; } return true; } void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) { MuxGuard g(mLock); RecordId recId = getRecordIdLocked(propValue); auto it = mPropertyValues.find(recId); if (it != mPropertyValues.end()) { mPropertyValues.erase(it); } } void VehiclePropertyStore::removeValuesForProperty(int32_t propId) { MuxGuard g(mLock); auto range = findRangeLocked(propId); mPropertyValues.erase(range.first, range.second); } std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const { MuxGuard g(mLock); std::vector<VehiclePropValue> allValues; allValues.reserve(mPropertyValues.size()); for (auto&& it : mPropertyValues) { allValues.push_back(it.second); } return allValues; } std::vector<VehiclePropValue> VehiclePropertyStore::readValuesForProperty(int32_t propId) const { std::vector<VehiclePropValue> values; MuxGuard g(mLock); auto range = findRangeLocked(propId); for (auto it = range.first; it != range.second; ++it) { values.push_back(it->second); } return values; } std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull( const VehiclePropValue& request) const { MuxGuard g(mLock); RecordId recId = getRecordIdLocked(request); const VehiclePropValue* internalValue = getValueOrNullLocked(recId); return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr; } std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull( int32_t prop, int32_t area, int64_t token) const { RecordId recId = {prop, isGlobalProp(prop) ? 0 : area, token }; MuxGuard g(mLock); const VehiclePropValue* internalValue = getValueOrNullLocked(recId); return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr; } std::vector<VehiclePropConfig> VehiclePropertyStore::getAllConfigs() const { MuxGuard g(mLock); std::vector<VehiclePropConfig> configs; configs.reserve(mConfigs.size()); for (auto&& recordConfigIt: mConfigs) { configs.push_back(recordConfigIt.second.propConfig); } return configs; } const VehiclePropConfig* VehiclePropertyStore::getConfigOrNull(int32_t propId) const { MuxGuard g(mLock); auto recordConfigIt = mConfigs.find(propId); return recordConfigIt != mConfigs.end() ? &recordConfigIt->second.propConfig : nullptr; } const VehiclePropConfig* VehiclePropertyStore::getConfigOrDie(int32_t propId) const { auto cfg = getConfigOrNull(propId); if (!cfg) { ALOGW("%s: config not found for property: 0x%x", __func__, propId); abort(); } return cfg; } VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked( const VehiclePropValue& valuePrototype) const { RecordId recId = { .prop = valuePrototype.prop, .area = isGlobalProp(valuePrototype.prop) ? 0 : valuePrototype.areaId, .token = 0 }; auto it = mConfigs.find(recId.prop); if (it == mConfigs.end()) return {}; if (it->second.tokenFunction != nullptr) { recId.token = it->second.tokenFunction(valuePrototype); } return recId; } const VehiclePropValue* VehiclePropertyStore::getValueOrNullLocked( const VehiclePropertyStore::RecordId& recId) const { auto it = mPropertyValues.find(recId); return it == mPropertyValues.end() ? nullptr : &it->second; } VehiclePropertyStore::PropertyMapRange VehiclePropertyStore::findRangeLocked(int32_t propId) const { // Based on the fact that mPropertyValues is a sorted map by RecordId. auto beginIt = mPropertyValues.lower_bound( RecordId { propId, INT32_MIN, 0 }); auto endIt = mPropertyValues.lower_bound( RecordId { propId + 1, INT32_MIN, 0 }); return PropertyMapRange { beginIt, endIt }; } } // namespace V2_0 } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +187 −106 Original line number Diff line number Diff line Loading @@ -33,38 +33,64 @@ 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[] { { .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 = { .floatValues = {0.0f} } }, { .config = { .prop = toInt(VehicleProperty::CURRENT_GEAR), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } } }, { .config = { .prop = toInt(VehicleProperty::PARKING_BRAKE_ON), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = {0} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_POWER_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -73,8 +99,11 @@ const VehiclePropConfig kVehicleProperties[] = { // kHvacPowerProperties. .configString = "0x12400500,0x12400501" // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_DEFROSTER), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -82,29 +111,41 @@ const VehiclePropConfig kVehicleProperties[] = { VehicleAreaWindow::FRONT_WINDSHIELD | VehicleAreaWindow::REAR_WINDSHIELD }, .initialValue = { .int32Values = {0} } // Will be used for all areas. }, { .config = { .prop = toInt(VehicleProperty::HVAC_RECIRC_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_AC_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_AUTO_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_FAN_SPEED), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -117,15 +158,21 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialValue = { .int32Values = {3} } }, { .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, Loading @@ -145,8 +192,19 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialAreaValues = { { toInt(VehicleAreaZone::ROW_1_LEFT), { .floatValues = {16} } }, { toInt(VehicleAreaZone::ROW_1_RIGHT), { .floatValues = {20} } } } }, { .config = { .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE), .access = VehiclePropertyAccess::READ, // TODO(bryaneyler): Support ON_CHANGE as well. Loading @@ -154,32 +212,47 @@ const VehiclePropConfig kVehicleProperties[] = { .minSampleRate = 1.0f, .maxSampleRate = 2.0f, }, .initialValue = { .floatValues = {25.0f} } }, { .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, Loading @@ -190,19 +263,27 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialValue = { .int32Values = {7} } }, { .config = { .prop = toInt(VehicleProperty::IGNITION_STATE), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = { toInt(VehicleIgnitionState::ON) } } }, { .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} } } }; Loading Loading
automotive/vehicle/2.0/default/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \ common/src/SubscriptionManager.cpp \ common/src/VehicleHalManager.cpp \ common/src/VehicleObjectPool.cpp \ common/src/VehiclePropertyStore.cpp \ common/src/VehicleUtils.cpp \ LOCAL_C_INCLUDES := \ Loading Loading @@ -72,9 +73,10 @@ include $(CLEAR_VARS) LOCAL_MODULE:= $(vhal_v2_0)-default-impl-lib LOCAL_SRC_FILES:= \ impl/vhal_v2_0/DefaultVehicleHal.cpp \ impl/vhal_v2_0/EmulatedVehicleHal.cpp \ impl/vhal_v2_0/VehicleEmulator.cpp \ impl/vhal_v2_0/PipeComm.cpp \ impl/vhal_v2_0/SocketComm.cpp impl/vhal_v2_0/SocketComm.cpp \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/impl/vhal_v2_0 Loading
automotive/vehicle/2.0/default/VehicleService.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -21,14 +21,16 @@ #include <iostream> #include <vhal_v2_0/VehicleHalManager.h> #include <vhal_v2_0/DefaultVehicleHal.h> #include <vhal_v2_0/EmulatedVehicleHal.h> using namespace android; using namespace android::hardware; using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto hal = std::make_unique<impl::DefaultVehicleHal>(); auto store = std::make_unique<VehiclePropertyStore>(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get()); auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get()); auto service = std::make_unique<VehicleHalManager>(hal.get()); configureRpcThreadpool(1, true /* callerWillJoin */); Loading
automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h 0 → 100644 +104 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_ #define android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_ #include <cstdint> #include <unordered_map> #include <memory> #include <mutex> #include <android/hardware/automotive/vehicle/2.0/IVehicle.h> namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace V2_0 { /** * Encapsulates work related to storing and accessing configuration, storing and modifying * vehicle property values. * * VehiclePropertyValues stored in a sorted map thus it makes easier to get range of values, e.g. * to get value for all areas for particular property. * * This class is thread-safe, however it uses blocking synchronization across all methods. */ class VehiclePropertyStore { public: /* Function that used to calculate unique token for given VehiclePropValue */ using TokenFunction = std::function<int64_t(const VehiclePropValue& value)>; private: struct RecordConfig { VehiclePropConfig propConfig; TokenFunction tokenFunction; }; struct RecordId { int32_t prop; int32_t area; int64_t token; bool operator==(const RecordId& other) const; bool operator<(const RecordId& other) const; }; using PropertyMap = std::map<RecordId, VehiclePropValue>; using PropertyMapRange = std::pair<PropertyMap::const_iterator, PropertyMap::const_iterator>; public: void registerProperty(const VehiclePropConfig& config, TokenFunction tokenFunc = nullptr); /* Stores provided value. Returns true if value was written returns false if config for * example wasn't registered. */ bool writeValue(const VehiclePropValue& propValue); void removeValue(const VehiclePropValue& propValue); void removeValuesForProperty(int32_t propId); std::vector<VehiclePropValue> readAllValues() const; std::vector<VehiclePropValue> readValuesForProperty(int32_t propId) const; std::unique_ptr<VehiclePropValue> readValueOrNull(const VehiclePropValue& request) const; std::unique_ptr<VehiclePropValue> readValueOrNull(int32_t prop, int32_t area = 0, int64_t token = 0) const; std::vector<VehiclePropConfig> getAllConfigs() const; const VehiclePropConfig* getConfigOrNull(int32_t propId) const; const VehiclePropConfig* getConfigOrDie(int32_t propId) const; private: RecordId getRecordIdLocked(const VehiclePropValue& valuePrototype) const; const VehiclePropValue* getValueOrNullLocked(const RecordId& recId) const; PropertyMapRange findRangeLocked(int32_t propId) const; private: using MuxGuard = std::lock_guard<std::mutex>; mutable std::mutex mLock; std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs; PropertyMap mPropertyValues; // Sorted map of RecordId : VehiclePropValue. }; } // namespace V2_0 } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android #endif //android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_
automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VehiclePropertyStore" #include <android/log.h> #include <common/include/vhal_v2_0/VehicleUtils.h> #include "VehiclePropertyStore.h" namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace V2_0 { bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const { return prop == other.prop && area == other.area && token == other.token; } bool VehiclePropertyStore::RecordId::operator<(const VehiclePropertyStore::RecordId& other) const { return prop < other.prop || (prop == other.prop && area < other.area) || (prop == other.prop && area == other.area && token < other.token); } void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config, VehiclePropertyStore::TokenFunction tokenFunc) { MuxGuard g(mLock); mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } }); } bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue) { MuxGuard g(mLock); if (!mConfigs.count(propValue.prop)) return false; RecordId recId = getRecordIdLocked(propValue); VehiclePropValue* valueToUpdate = const_cast<VehiclePropValue*>(getValueOrNullLocked(recId)); if (valueToUpdate == nullptr) { mPropertyValues.insert({ recId, propValue }); } else { valueToUpdate->timestamp = propValue.timestamp; valueToUpdate->value = propValue.value; } return true; } void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) { MuxGuard g(mLock); RecordId recId = getRecordIdLocked(propValue); auto it = mPropertyValues.find(recId); if (it != mPropertyValues.end()) { mPropertyValues.erase(it); } } void VehiclePropertyStore::removeValuesForProperty(int32_t propId) { MuxGuard g(mLock); auto range = findRangeLocked(propId); mPropertyValues.erase(range.first, range.second); } std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const { MuxGuard g(mLock); std::vector<VehiclePropValue> allValues; allValues.reserve(mPropertyValues.size()); for (auto&& it : mPropertyValues) { allValues.push_back(it.second); } return allValues; } std::vector<VehiclePropValue> VehiclePropertyStore::readValuesForProperty(int32_t propId) const { std::vector<VehiclePropValue> values; MuxGuard g(mLock); auto range = findRangeLocked(propId); for (auto it = range.first; it != range.second; ++it) { values.push_back(it->second); } return values; } std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull( const VehiclePropValue& request) const { MuxGuard g(mLock); RecordId recId = getRecordIdLocked(request); const VehiclePropValue* internalValue = getValueOrNullLocked(recId); return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr; } std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull( int32_t prop, int32_t area, int64_t token) const { RecordId recId = {prop, isGlobalProp(prop) ? 0 : area, token }; MuxGuard g(mLock); const VehiclePropValue* internalValue = getValueOrNullLocked(recId); return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr; } std::vector<VehiclePropConfig> VehiclePropertyStore::getAllConfigs() const { MuxGuard g(mLock); std::vector<VehiclePropConfig> configs; configs.reserve(mConfigs.size()); for (auto&& recordConfigIt: mConfigs) { configs.push_back(recordConfigIt.second.propConfig); } return configs; } const VehiclePropConfig* VehiclePropertyStore::getConfigOrNull(int32_t propId) const { MuxGuard g(mLock); auto recordConfigIt = mConfigs.find(propId); return recordConfigIt != mConfigs.end() ? &recordConfigIt->second.propConfig : nullptr; } const VehiclePropConfig* VehiclePropertyStore::getConfigOrDie(int32_t propId) const { auto cfg = getConfigOrNull(propId); if (!cfg) { ALOGW("%s: config not found for property: 0x%x", __func__, propId); abort(); } return cfg; } VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked( const VehiclePropValue& valuePrototype) const { RecordId recId = { .prop = valuePrototype.prop, .area = isGlobalProp(valuePrototype.prop) ? 0 : valuePrototype.areaId, .token = 0 }; auto it = mConfigs.find(recId.prop); if (it == mConfigs.end()) return {}; if (it->second.tokenFunction != nullptr) { recId.token = it->second.tokenFunction(valuePrototype); } return recId; } const VehiclePropValue* VehiclePropertyStore::getValueOrNullLocked( const VehiclePropertyStore::RecordId& recId) const { auto it = mPropertyValues.find(recId); return it == mPropertyValues.end() ? nullptr : &it->second; } VehiclePropertyStore::PropertyMapRange VehiclePropertyStore::findRangeLocked(int32_t propId) const { // Based on the fact that mPropertyValues is a sorted map by RecordId. auto beginIt = mPropertyValues.lower_bound( RecordId { propId, INT32_MIN, 0 }); auto endIt = mPropertyValues.lower_bound( RecordId { propId + 1, INT32_MIN, 0 }); return PropertyMapRange { beginIt, endIt }; } } // namespace V2_0 } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android
automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +187 −106 Original line number Diff line number Diff line Loading @@ -33,38 +33,64 @@ 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[] { { .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 = { .floatValues = {0.0f} } }, { .config = { .prop = toInt(VehicleProperty::CURRENT_GEAR), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } } }, { .config = { .prop = toInt(VehicleProperty::PARKING_BRAKE_ON), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = {0} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_POWER_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -73,8 +99,11 @@ const VehiclePropConfig kVehicleProperties[] = { // kHvacPowerProperties. .configString = "0x12400500,0x12400501" // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_DEFROSTER), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -82,29 +111,41 @@ const VehiclePropConfig kVehicleProperties[] = { VehicleAreaWindow::FRONT_WINDSHIELD | VehicleAreaWindow::REAR_WINDSHIELD }, .initialValue = { .int32Values = {0} } // Will be used for all areas. }, { .config = { .prop = toInt(VehicleProperty::HVAC_RECIRC_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_AC_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_AUTO_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .supportedAreas = toInt(VehicleAreaZone::ROW_1) }, .initialValue = { .int32Values = {1} } }, { .config = { .prop = toInt(VehicleProperty::HVAC_FAN_SPEED), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, Loading @@ -117,15 +158,21 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialValue = { .int32Values = {3} } }, { .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, Loading @@ -145,8 +192,19 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialAreaValues = { { toInt(VehicleAreaZone::ROW_1_LEFT), { .floatValues = {16} } }, { toInt(VehicleAreaZone::ROW_1_RIGHT), { .floatValues = {20} } } } }, { .config = { .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE), .access = VehiclePropertyAccess::READ, // TODO(bryaneyler): Support ON_CHANGE as well. Loading @@ -154,32 +212,47 @@ const VehiclePropConfig kVehicleProperties[] = { .minSampleRate = 1.0f, .maxSampleRate = 2.0f, }, .initialValue = { .floatValues = {25.0f} } }, { .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, Loading @@ -190,19 +263,27 @@ const VehiclePropConfig kVehicleProperties[] = { } } }, .initialValue = { .int32Values = {7} } }, { .config = { .prop = toInt(VehicleProperty::IGNITION_STATE), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, .initialValue = { .int32Values = { toInt(VehicleIgnitionState::ON) } } }, { .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} } } }; Loading