mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "Use ObjectPool objects in property store."
This commit is contained in:
@@ -22,6 +22,7 @@ cc_defaults {
|
||||
name: "VehicleHalDefaults",
|
||||
static_libs: [
|
||||
"android.hardware.automotive.vehicle-V1-ndk",
|
||||
"libmath",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <VehicleHalTypes.h>
|
||||
#include <VehicleObjectPool.h>
|
||||
#include <android-base/result.h>
|
||||
#include <android-base/thread_annotations.h>
|
||||
|
||||
@@ -41,6 +42,9 @@ namespace vehicle {
|
||||
// This class is thread-safe, however it uses blocking synchronization across all methods.
|
||||
class VehiclePropertyStore {
|
||||
public:
|
||||
explicit VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)
|
||||
: mValuePool(valuePool) {}
|
||||
|
||||
// Function that used to calculate unique token for given VehiclePropValue.
|
||||
using TokenFunction = ::std::function<int64_t(
|
||||
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)>;
|
||||
@@ -53,10 +57,13 @@ class VehiclePropertyStore {
|
||||
const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config,
|
||||
TokenFunction tokenFunc = nullptr);
|
||||
|
||||
// Stores provided value. Returns true if value was written returns false if config wasn't
|
||||
// registered.
|
||||
::android::base::Result<void> writeValue(
|
||||
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
|
||||
// Stores provided value. Returns error if config wasn't registered. If 'updateStatus' is
|
||||
// true, the 'status' in 'propValue' would be stored. Otherwise, if this is a new value,
|
||||
// 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
|
||||
// override an existing value, the status for the existing value would be used for the
|
||||
// overridden value.
|
||||
::android::base::Result<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
|
||||
bool updateStatus = false);
|
||||
|
||||
// Remove a given property value from the property store. The 'propValue' would be used to
|
||||
// generate the key for the value to remove.
|
||||
@@ -67,24 +74,19 @@ class VehiclePropertyStore {
|
||||
void removeValuesForProperty(int32_t propId);
|
||||
|
||||
// Read all the stored values.
|
||||
std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue> readAllValues()
|
||||
const;
|
||||
std::vector<VehiclePropValuePool::RecyclableType> readAllValues() const;
|
||||
|
||||
// Read all the values for the property.
|
||||
::android::base::Result<
|
||||
std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
|
||||
::android::base::Result<std::vector<VehiclePropValuePool::RecyclableType>>
|
||||
readValuesForProperty(int32_t propId) const;
|
||||
|
||||
// Read the value for the requested property.
|
||||
::android::base::Result<
|
||||
std::unique_ptr<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
|
||||
readValue(
|
||||
::android::base::Result<VehiclePropValuePool::RecyclableType> readValue(
|
||||
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& request) const;
|
||||
|
||||
// Read the value for the requested property.
|
||||
::android::base::Result<
|
||||
std::unique_ptr<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
|
||||
readValue(int32_t prop, int32_t area = 0, int64_t token = 0) const;
|
||||
::android::base::Result<VehiclePropValuePool::RecyclableType> readValue(
|
||||
int32_t prop, int32_t area = 0, int64_t token = 0) const;
|
||||
|
||||
// Get all property configs.
|
||||
std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
|
||||
@@ -100,20 +102,25 @@ class VehiclePropertyStore {
|
||||
int32_t area;
|
||||
int64_t token;
|
||||
|
||||
bool operator==(const RecordId& other) const;
|
||||
bool operator<(const RecordId& other) const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
bool operator==(const RecordId& other) const;
|
||||
};
|
||||
|
||||
struct RecordIdHash {
|
||||
size_t operator()(RecordId const& recordId) const;
|
||||
};
|
||||
|
||||
struct Record {
|
||||
::aidl::android::hardware::automotive::vehicle::VehiclePropConfig propConfig;
|
||||
TokenFunction tokenFunction;
|
||||
std::map<RecordId, ::aidl::android::hardware::automotive::vehicle::VehiclePropValue> values;
|
||||
std::unordered_map<RecordId, VehiclePropValuePool::RecyclableType, RecordIdHash> values;
|
||||
};
|
||||
|
||||
mutable std::mutex mLock;
|
||||
std::unordered_map<int32_t, Record> mRecordsByPropId GUARDED_BY(mLock);
|
||||
// {@code VehiclePropValuePool} is thread-safe.
|
||||
std::shared_ptr<VehiclePropValuePool> mValuePool;
|
||||
|
||||
const Record* getRecordLocked(int32_t propId) const;
|
||||
|
||||
@@ -123,9 +130,8 @@ class VehiclePropertyStore {
|
||||
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue,
|
||||
const Record& record) const;
|
||||
|
||||
::android::base::Result<
|
||||
std::unique_ptr<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
|
||||
readValueLocked(const RecordId& recId, const Record& record) const;
|
||||
::android::base::Result<VehiclePropValuePool::RecyclableType> readValueLocked(
|
||||
const RecordId& recId, const Record& record) const;
|
||||
};
|
||||
|
||||
} // namespace vehicle
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <VehicleUtils.h>
|
||||
#include <android-base/format.h>
|
||||
#include <math/HashCombine.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
@@ -29,6 +30,7 @@ namespace vehicle {
|
||||
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
|
||||
using ::android::base::Result;
|
||||
|
||||
@@ -36,14 +38,17 @@ bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::Reco
|
||||
return area == other.area && token == other.token;
|
||||
}
|
||||
|
||||
bool VehiclePropertyStore::RecordId::operator<(const VehiclePropertyStore::RecordId& other) const {
|
||||
return area < other.area || (area == other.area && token < other.token);
|
||||
}
|
||||
|
||||
std::string VehiclePropertyStore::RecordId::toString() const {
|
||||
return ::fmt::format("RecordID{{.areaId={:d}, .token={:d}}}", area, token);
|
||||
}
|
||||
|
||||
size_t VehiclePropertyStore::RecordIdHash::operator()(RecordId const& recordId) const {
|
||||
size_t res = 0;
|
||||
hashCombine(res, recordId.area);
|
||||
hashCombine(res, recordId.token);
|
||||
return res;
|
||||
}
|
||||
|
||||
const VehiclePropertyStore::Record* VehiclePropertyStore::getRecordLocked(int32_t propId) const
|
||||
REQUIRES(mLock) {
|
||||
auto RecordIt = mRecordsByPropId.find(propId);
|
||||
@@ -68,13 +73,13 @@ VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked(
|
||||
return recId;
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<VehiclePropValue>> VehiclePropertyStore::readValueLocked(
|
||||
Result<VehiclePropValuePool::RecyclableType> VehiclePropertyStore::readValueLocked(
|
||||
const RecordId& recId, const Record& record) const REQUIRES(mLock) {
|
||||
auto it = record.values.find(recId);
|
||||
if (it == record.values.end()) {
|
||||
return Errorf("Record ID: {} is not found", recId.toString());
|
||||
}
|
||||
return std::make_unique<VehiclePropValue>(it->second);
|
||||
return mValuePool->obtain(*(it->second));
|
||||
}
|
||||
|
||||
void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
|
||||
@@ -87,36 +92,42 @@ void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
|
||||
};
|
||||
}
|
||||
|
||||
Result<void> VehiclePropertyStore::writeValue(const VehiclePropValue& propValue) {
|
||||
Result<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::RecyclableType propValue,
|
||||
bool updateStatus) {
|
||||
std::lock_guard<std::mutex> g(mLock);
|
||||
|
||||
VehiclePropertyStore::Record* record = getRecordLocked(propValue.prop);
|
||||
VehiclePropertyStore::Record* record = getRecordLocked(propValue->prop);
|
||||
if (record == nullptr) {
|
||||
return Errorf("property: {:d} not registered", propValue.prop);
|
||||
return Errorf("property: {:d} not registered", propValue->prop);
|
||||
}
|
||||
|
||||
if (!isGlobalProp(propValue.prop) && getAreaConfig(propValue, record->propConfig) == nullptr) {
|
||||
return Errorf("no config for property: {:d} area: {:d}", propValue.prop, propValue.areaId);
|
||||
if (!isGlobalProp(propValue->prop) &&
|
||||
getAreaConfig(*propValue, record->propConfig) == nullptr) {
|
||||
return Errorf("no config for property: {:d} area: {:d}", propValue->prop,
|
||||
propValue->areaId);
|
||||
}
|
||||
|
||||
VehiclePropertyStore::RecordId recId = getRecordIdLocked(propValue, *record);
|
||||
VehiclePropertyStore::RecordId recId = getRecordIdLocked(*propValue, *record);
|
||||
auto it = record->values.find(recId);
|
||||
if (it == record->values.end()) {
|
||||
record->values[recId] = propValue;
|
||||
record->values[recId] = std::move(propValue);
|
||||
if (!updateStatus) {
|
||||
record->values[recId]->status = VehiclePropertyStatus::AVAILABLE;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
VehiclePropValue* valueToUpdate = &(it->second);
|
||||
|
||||
const VehiclePropValue* valueToUpdate = it->second.get();
|
||||
long oldTimestamp = valueToUpdate->timestamp;
|
||||
VehiclePropertyStatus oldStatus = valueToUpdate->status;
|
||||
// propValue is outdated and drops it.
|
||||
if (valueToUpdate->timestamp > propValue.timestamp) {
|
||||
return Errorf("outdated timestamp: {:d}", propValue.timestamp);
|
||||
if (oldTimestamp > propValue->timestamp) {
|
||||
return Errorf("outdated timestamp: {:d}", propValue->timestamp);
|
||||
}
|
||||
// Update the propertyValue.
|
||||
// The timestamp in propertyStore should only be updated by the server side. It indicates
|
||||
// the time when the event is generated by the server.
|
||||
valueToUpdate->timestamp = propValue.timestamp;
|
||||
valueToUpdate->value = propValue.value;
|
||||
valueToUpdate->status = propValue.status;
|
||||
record->values[recId] = std::move(propValue);
|
||||
if (!updateStatus) {
|
||||
record->values[recId]->status = oldStatus;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -145,25 +156,25 @@ void VehiclePropertyStore::removeValuesForProperty(int32_t propId) {
|
||||
record->values.clear();
|
||||
}
|
||||
|
||||
std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const {
|
||||
std::vector<VehiclePropValuePool::RecyclableType> VehiclePropertyStore::readAllValues() const {
|
||||
std::lock_guard<std::mutex> g(mLock);
|
||||
|
||||
std::vector<VehiclePropValue> allValues;
|
||||
std::vector<VehiclePropValuePool::RecyclableType> allValues;
|
||||
|
||||
for (auto const& [_, record] : mRecordsByPropId) {
|
||||
for (auto const& [_, value] : record.values) {
|
||||
allValues.push_back(value);
|
||||
allValues.push_back(std::move(mValuePool->obtain(*value)));
|
||||
}
|
||||
}
|
||||
|
||||
return allValues;
|
||||
}
|
||||
|
||||
Result<std::vector<VehiclePropValue>> VehiclePropertyStore::readValuesForProperty(
|
||||
int32_t propId) const {
|
||||
Result<std::vector<VehiclePropValuePool::RecyclableType>>
|
||||
VehiclePropertyStore::readValuesForProperty(int32_t propId) const {
|
||||
std::lock_guard<std::mutex> g(mLock);
|
||||
|
||||
std::vector<VehiclePropValue> values;
|
||||
std::vector<VehiclePropValuePool::RecyclableType> values;
|
||||
|
||||
const VehiclePropertyStore::Record* record = getRecordLocked(propId);
|
||||
if (record == nullptr) {
|
||||
@@ -171,12 +182,12 @@ Result<std::vector<VehiclePropValue>> VehiclePropertyStore::readValuesForPropert
|
||||
}
|
||||
|
||||
for (auto const& [_, value] : record->values) {
|
||||
values.push_back(value);
|
||||
values.push_back(std::move(mValuePool->obtain(*value)));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<VehiclePropValue>> VehiclePropertyStore::readValue(
|
||||
Result<VehiclePropValuePool::RecyclableType> VehiclePropertyStore::readValue(
|
||||
const VehiclePropValue& propValue) const {
|
||||
std::lock_guard<std::mutex> g(mLock);
|
||||
|
||||
@@ -189,9 +200,9 @@ Result<std::unique_ptr<VehiclePropValue>> VehiclePropertyStore::readValue(
|
||||
return readValueLocked(recId, *record);
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<VehiclePropValue>> VehiclePropertyStore::readValue(int32_t propId,
|
||||
int32_t areaId,
|
||||
int64_t token) const {
|
||||
Result<VehiclePropValuePool::RecyclableType> VehiclePropertyStore::readValue(int32_t propId,
|
||||
int32_t areaId,
|
||||
int64_t token) const {
|
||||
std::lock_guard<std::mutex> g(mLock);
|
||||
|
||||
const VehiclePropertyStore::Record* record = getRecordLocked(propId);
|
||||
|
||||
@@ -32,6 +32,8 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
|
||||
using ::android::base::Result;
|
||||
using ::testing::ElementsAre;
|
||||
@@ -51,6 +53,17 @@ int64_t timestampToken(const VehiclePropValue& value) {
|
||||
return value.timestamp;
|
||||
}
|
||||
|
||||
// A helper function to turn value pointer to value structure for easier comparison.
|
||||
std::vector<VehiclePropValue> convertValuePtrsToValues(
|
||||
const std::vector<VehiclePropValuePool::RecyclableType>& values) {
|
||||
std::vector<VehiclePropValue> returnValues;
|
||||
returnValues.reserve(values.size());
|
||||
for (auto& value : values) {
|
||||
returnValues.push_back(*value);
|
||||
}
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class VehiclePropertyStoreTest : public ::testing::Test {
|
||||
@@ -70,30 +83,33 @@ class VehiclePropertyStoreTest : public ::testing::Test {
|
||||
VehicleAreaConfig{.areaId = WHEEL_REAR_LEFT},
|
||||
VehicleAreaConfig{.areaId = WHEEL_REAR_RIGHT}},
|
||||
};
|
||||
mStore.registerProperty(mConfigFuelCapacity);
|
||||
mStore.registerProperty(configTirePressure);
|
||||
mValuePool = std::make_shared<VehiclePropValuePool>();
|
||||
mStore.reset(new VehiclePropertyStore(mValuePool));
|
||||
mStore->registerProperty(mConfigFuelCapacity);
|
||||
mStore->registerProperty(configTirePressure);
|
||||
}
|
||||
|
||||
VehiclePropertyStore mStore;
|
||||
VehiclePropConfig mConfigFuelCapacity;
|
||||
std::shared_ptr<VehiclePropValuePool> mValuePool;
|
||||
std::unique_ptr<VehiclePropertyStore> mStore;
|
||||
};
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testGetAllConfigs) {
|
||||
std::vector<VehiclePropConfig> configs = mStore.getAllConfigs();
|
||||
std::vector<VehiclePropConfig> configs = mStore->getAllConfigs();
|
||||
|
||||
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testGetConfig) {
|
||||
Result<const VehiclePropConfig*> result =
|
||||
mStore.getConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
mStore->getConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(*(result.value()), mConfigFuelCapacity);
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testGetConfigWithInvalidPropId) {
|
||||
Result<const VehiclePropConfig*> result = mStore.getConfig(INVALID_PROP_ID);
|
||||
Result<const VehiclePropConfig*> result = mStore->getConfig(INVALID_PROP_ID);
|
||||
|
||||
ASSERT_FALSE(result.ok()) << "expect error when getting a config for an invalid property ID";
|
||||
}
|
||||
@@ -122,46 +138,47 @@ std::vector<VehiclePropValue> getTestPropValues() {
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueOk) {
|
||||
auto values = getTestPropValues();
|
||||
|
||||
ASSERT_RESULT_OK(mStore.writeValue(values[0]));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(values[0])));
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testReadAllValues) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
auto gotValues = mStore.readAllValues();
|
||||
auto gotValues = mStore->readAllValues();
|
||||
|
||||
ASSERT_THAT(gotValues, WhenSortedBy(propValueCmp, Eq(values)));
|
||||
ASSERT_THAT(convertValuePtrsToValues(gotValues), WhenSortedBy(propValueCmp, Eq(values)));
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValuesForPropertyOneValue) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
auto result = mStore.readValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
auto result = mStore->readValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_THAT(result.value(), ElementsAre(values[0]));
|
||||
ASSERT_THAT(convertValuePtrsToValues(result.value()), ElementsAre(values[0]));
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValuesForPropertyMultipleValues) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
auto result = mStore.readValuesForProperty(toInt(VehicleProperty::TIRE_PRESSURE));
|
||||
auto result = mStore->readValuesForProperty(toInt(VehicleProperty::TIRE_PRESSURE));
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_THAT(result.value(), WhenSortedBy(propValueCmp, ElementsAre(values[1], values[2])));
|
||||
ASSERT_THAT(convertValuePtrsToValues(result.value()),
|
||||
WhenSortedBy(propValueCmp, ElementsAre(values[1], values[2])));
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValuesForPropertyError) {
|
||||
auto result = mStore.readValuesForProperty(INVALID_PROP_ID);
|
||||
auto result = mStore->readValuesForProperty(INVALID_PROP_ID);
|
||||
|
||||
ASSERT_FALSE(result.ok()) << "expect error when reading values for an invalid property";
|
||||
}
|
||||
@@ -169,7 +186,7 @@ TEST_F(VehiclePropertyStoreTest, testReadValuesForPropertyError) {
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValueOk) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
VehiclePropValue requestValue = {
|
||||
@@ -177,7 +194,7 @@ TEST_F(VehiclePropertyStoreTest, testReadValueOk) {
|
||||
.areaId = WHEEL_FRONT_LEFT,
|
||||
};
|
||||
|
||||
auto result = mStore.readValue(requestValue);
|
||||
auto result = mStore->readValue(requestValue);
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(*(result.value()), values[1]);
|
||||
@@ -186,10 +203,10 @@ TEST_F(VehiclePropertyStoreTest, testReadValueOk) {
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValueByPropIdOk) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
auto result = mStore.readValue(toInt(VehicleProperty::TIRE_PRESSURE), WHEEL_FRONT_RIGHT);
|
||||
auto result = mStore->readValue(toInt(VehicleProperty::TIRE_PRESSURE), WHEEL_FRONT_RIGHT);
|
||||
|
||||
ASSERT_EQ(*(result.value()), values[2]);
|
||||
}
|
||||
@@ -197,50 +214,47 @@ TEST_F(VehiclePropertyStoreTest, testReadValueByPropIdOk) {
|
||||
TEST_F(VehiclePropertyStoreTest, testReadValueError) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
auto result = mStore.readValue(toInt(VehicleProperty::TIRE_PRESSURE), WHEEL_REAR_LEFT);
|
||||
auto result = mStore->readValue(toInt(VehicleProperty::TIRE_PRESSURE), WHEEL_REAR_LEFT);
|
||||
|
||||
ASSERT_FALSE(result.ok()) << "expect error when reading a value that has not been written";
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueError) {
|
||||
ASSERT_FALSE(mStore.writeValue({
|
||||
.prop = INVALID_PROP_ID,
|
||||
.value = {.floatValues = {1.0}},
|
||||
})
|
||||
.ok())
|
||||
auto v = mValuePool->obtain(VehiclePropertyType::FLOAT);
|
||||
v->prop = INVALID_PROP_ID;
|
||||
v->value.floatValues = {1.0};
|
||||
ASSERT_FALSE(mStore->writeValue(std::move(v)).ok())
|
||||
<< "expect error when writing value for an invalid property ID";
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueNoAreaConfig) {
|
||||
ASSERT_FALSE(mStore.writeValue({
|
||||
.prop = toInt(VehicleProperty::TIRE_PRESSURE),
|
||||
.value = {.floatValues = {180.0}},
|
||||
// There is no config for ALL_WHEELS.
|
||||
.areaId = ALL_WHEELS,
|
||||
})
|
||||
.ok())
|
||||
auto v = mValuePool->obtain(VehiclePropertyType::FLOAT);
|
||||
v->prop = toInt(VehicleProperty::TIRE_PRESSURE);
|
||||
v->value.floatValues = {1.0};
|
||||
// There is no config for ALL_WHEELS.
|
||||
v->areaId = ALL_WHEELS;
|
||||
ASSERT_FALSE(mStore->writeValue(std::move(v)).ok())
|
||||
<< "expect error when writing value for an area without config";
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteOutdatedValue) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue({
|
||||
.timestamp = 1,
|
||||
.prop = toInt(VehicleProperty::TIRE_PRESSURE),
|
||||
.value = {.floatValues = {180.0}},
|
||||
.areaId = WHEEL_FRONT_LEFT,
|
||||
}));
|
||||
auto v = mValuePool->obtain(VehiclePropertyType::FLOAT);
|
||||
v->timestamp = 1;
|
||||
v->prop = toInt(VehicleProperty::TIRE_PRESSURE);
|
||||
v->value.floatValues = {180.0};
|
||||
v->areaId = WHEEL_FRONT_LEFT;
|
||||
ASSERT_RESULT_OK(mStore->writeValue(std::move(v)));
|
||||
|
||||
// Write an older value.
|
||||
ASSERT_FALSE(mStore.writeValue({
|
||||
.timestamp = 0,
|
||||
.prop = toInt(VehicleProperty::TIRE_PRESSURE),
|
||||
.value = {.floatValues = {180.0}},
|
||||
.areaId = WHEEL_FRONT_LEFT,
|
||||
})
|
||||
.ok())
|
||||
auto v2 = mValuePool->obtain(VehiclePropertyType::FLOAT);
|
||||
v2->timestamp = 0;
|
||||
v2->prop = toInt(VehicleProperty::TIRE_PRESSURE);
|
||||
v2->value.floatValues = {180.0};
|
||||
v2->areaId = WHEEL_FRONT_LEFT;
|
||||
ASSERT_FALSE(mStore->writeValue(std::move(v2)).ok())
|
||||
<< "expect error when writing an outdated value";
|
||||
}
|
||||
|
||||
@@ -251,7 +265,7 @@ TEST_F(VehiclePropertyStoreTest, testToken) {
|
||||
};
|
||||
|
||||
// Replace existing config.
|
||||
mStore.registerProperty(config, timestampToken);
|
||||
mStore->registerProperty(config, timestampToken);
|
||||
|
||||
VehiclePropValue fuelCapacityValueToken1 = {
|
||||
.timestamp = 1,
|
||||
@@ -265,15 +279,15 @@ TEST_F(VehiclePropertyStoreTest, testToken) {
|
||||
.value = {.floatValues = {2.0}},
|
||||
};
|
||||
|
||||
ASSERT_RESULT_OK(mStore.writeValue(fuelCapacityValueToken1));
|
||||
ASSERT_RESULT_OK(mStore.writeValue(fuelCapacityValueToken2));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacityValueToken1)));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacityValueToken2)));
|
||||
|
||||
auto result = mStore.readValuesForProperty(propId);
|
||||
auto result = mStore->readValuesForProperty(propId);
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(result.value().size(), static_cast<size_t>(2));
|
||||
|
||||
auto tokenResult = mStore.readValue(propId, /*areaId=*/0, /*token=*/2);
|
||||
auto tokenResult = mStore->readValue(propId, /*areaId=*/0, /*token=*/2);
|
||||
|
||||
ASSERT_RESULT_OK(tokenResult);
|
||||
ASSERT_EQ(*(tokenResult.value()), fuelCapacityValueToken2);
|
||||
@@ -282,14 +296,14 @@ TEST_F(VehiclePropertyStoreTest, testToken) {
|
||||
TEST_F(VehiclePropertyStoreTest, testRemoveValue) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
|
||||
}
|
||||
|
||||
mStore.removeValue(values[0]);
|
||||
mStore->removeValue(values[0]);
|
||||
|
||||
ASSERT_FALSE(mStore.readValue(values[0]).ok()) << "expect error when reading a removed value";
|
||||
ASSERT_FALSE(mStore->readValue(values[0]).ok()) << "expect error when reading a removed value";
|
||||
|
||||
auto leftTirePressureResult = mStore.readValue(values[1]);
|
||||
auto leftTirePressureResult = mStore->readValue(values[1]);
|
||||
|
||||
ASSERT_RESULT_OK(leftTirePressureResult);
|
||||
ASSERT_EQ(*(leftTirePressureResult.value()), values[1]);
|
||||
@@ -298,16 +312,76 @@ TEST_F(VehiclePropertyStoreTest, testRemoveValue) {
|
||||
TEST_F(VehiclePropertyStoreTest, testRemoveValuesForProperty) {
|
||||
auto values = getTestPropValues();
|
||||
for (const auto& value : values) {
|
||||
ASSERT_RESULT_OK(mStore.writeValue(value));
|
||||
ASSERT_RESULT_OK(mStore->writeValue(std::move(mValuePool->obtain(value))));
|
||||
}
|
||||
|
||||
mStore.removeValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
mStore.removeValuesForProperty(toInt(VehicleProperty::TIRE_PRESSURE));
|
||||
mStore->removeValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
|
||||
mStore->removeValuesForProperty(toInt(VehicleProperty::TIRE_PRESSURE));
|
||||
|
||||
auto gotValues = mStore.readAllValues();
|
||||
auto gotValues = mStore->readAllValues();
|
||||
ASSERT_TRUE(gotValues.empty());
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueUpdateStatus) {
|
||||
VehiclePropValue fuelCapacity = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
.value = {.floatValues = {1.0}},
|
||||
};
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), true));
|
||||
|
||||
fuelCapacity.status = VehiclePropertyStatus::UNAVAILABLE;
|
||||
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), true));
|
||||
|
||||
VehiclePropValue requestValue = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
};
|
||||
|
||||
auto result = mStore->readValue(requestValue);
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(result.value()->status, VehiclePropertyStatus::UNAVAILABLE);
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueNoUpdateStatus) {
|
||||
VehiclePropValue fuelCapacity = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
.value = {.floatValues = {1.0}},
|
||||
};
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), true));
|
||||
|
||||
fuelCapacity.status = VehiclePropertyStatus::UNAVAILABLE;
|
||||
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), false));
|
||||
|
||||
VehiclePropValue requestValue = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
};
|
||||
|
||||
auto result = mStore->readValue(requestValue);
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(result.value()->status, VehiclePropertyStatus::AVAILABLE);
|
||||
}
|
||||
|
||||
TEST_F(VehiclePropertyStoreTest, testWriteValueNoUpdateStatusForNewValue) {
|
||||
VehiclePropValue fuelCapacity = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
.value = {.floatValues = {1.0}},
|
||||
.status = VehiclePropertyStatus::UNAVAILABLE,
|
||||
};
|
||||
ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), false));
|
||||
|
||||
VehiclePropValue requestValue = {
|
||||
.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
|
||||
};
|
||||
|
||||
auto result = mStore->readValue(requestValue);
|
||||
|
||||
ASSERT_RESULT_OK(result);
|
||||
ASSERT_EQ(result.value()->status, VehiclePropertyStatus::AVAILABLE);
|
||||
}
|
||||
|
||||
} // namespace vehicle
|
||||
} // namespace automotive
|
||||
} // namespace hardware
|
||||
|
||||
Reference in New Issue
Block a user