Use ObjectPool objects in property store.
Use object pool recyclable objects in property store API to improve
code efficiency. This would reduce the number of unnecssary copy of
property values.
This CL also adds a upateStatus option which by default is set to false,
so property from client would not override the property status.
Test: atest VehicleHalVehicleUtilsTest
Bug: 200737967
Change-Id: Ie96a41ee441e085e10ad1059b67c708ff7173ae0
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/Android.bp
index fc3d40b..94f590d 100644
--- a/automotive/vehicle/aidl/impl/Android.bp
+++ b/automotive/vehicle/aidl/impl/Android.bp
@@ -22,6 +22,7 @@
name: "VehicleHalDefaults",
static_libs: [
"android.hardware.automotive.vehicle-V1-ndk",
+ "libmath",
],
shared_libs: [
"libbase",
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index b19ab84..ababf5e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -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 @@
// 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 @@
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 @@
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 @@
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 @@
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
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index b660f36..2869d1d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -21,6 +21,7 @@
#include <VehicleUtils.h>
#include <android-base/format.h>
+#include <math/HashCombine.h>
namespace android {
namespace hardware {
@@ -29,6 +30,7 @@
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 @@
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 @@
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 @@
};
}
-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 @@
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 @@
}
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 @@
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);
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 8c70fea..f1d218d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -32,6 +32,8 @@
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 @@
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 @@
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 @@
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, 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 @@
.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, 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, 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 @@
};
// Replace existing config.
- mStore.registerProperty(config, timestampToken);
+ mStore->registerProperty(config, timestampToken);
VehiclePropValue fuelCapacityValueToken1 = {
.timestamp = 1,
@@ -265,15 +279,15 @@
.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, 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, 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