Merge "Add VTS test for timestamp for AIDL backend." into tm-dev am: fb5a427307
Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/17262799
Change-Id: I256bea8e1589bc7f8592cb2642998b3432583299
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index c33f3e9..c431d85 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -30,6 +30,7 @@
#include <hidl/ServiceManagement.h>
#include <inttypes.h>
#include <utils/Log.h>
+#include <utils/SystemClock.h>
#include <chrono>
#include <mutex>
@@ -67,6 +68,7 @@
private:
std::mutex mLock;
std::unordered_map<int32_t, size_t> mEventsCount GUARDED_BY(mLock);
+ std::unordered_map<int32_t, std::vector<int64_t>> mEventTimestamps GUARDED_BY(mLock);
std::condition_variable mEventCond;
public:
@@ -74,7 +76,9 @@
{
std::lock_guard<std::mutex> lockGuard(mLock);
for (auto& value : values) {
- mEventsCount[value->getPropId()] += 1;
+ int32_t propId = value->getPropId();
+ mEventsCount[propId] += 1;
+ mEventTimestamps[propId].push_back(value->getTimestamp());
}
}
mEventCond.notify_one();
@@ -94,6 +98,13 @@
});
}
+ std::vector<int64_t> getEventTimestamps(int32_t propId) {
+ {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ return mEventTimestamps[propId];
+ }
+ }
+
void reset() {
std::lock_guard<std::mutex> lockGuard(mLock);
mEventsCount.clear();
@@ -285,19 +296,59 @@
int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
- std::vector<SubscribeOptions> options = {
- SubscribeOptions{.propId = propId, .sampleRate = 10.0}};
+ auto propConfigsResult = mVhalClient->getPropConfigs({propId});
+
+ ASSERT_TRUE(propConfigsResult.ok()) << "Failed to get property config for PERF_VEHICLE_SPEED: "
+ << "error: " << propConfigsResult.error().message();
+ ASSERT_EQ(propConfigsResult.value().size(), 1u)
+ << "Expect to return 1 config for PERF_VEHICLE_SPEED";
+ auto& propConfig = propConfigsResult.value()[0];
+ float minSampleRate = propConfig->getMinSampleRate();
+ float maxSampleRate = propConfig->getMaxSampleRate();
+
+ if (minSampleRate < 1) {
+ GTEST_SKIP() << "Sample rate for vehicle speed < 1 times/sec, skip test since it would "
+ "take too long";
+ }
auto client = mVhalClient->getSubscriptionClient(mCallback);
ASSERT_NE(client, nullptr) << "Failed to get subscription client";
- auto result = client->subscribe(options);
+ auto result = client->subscribe({{.propId = propId, .sampleRate = minSampleRate}});
ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32
", error: %s",
propId, result.error().message().c_str());
- ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, 10, std::chrono::seconds(10)))
- << "Didn't get enough events for subscription";
+
+ if (mVhalClient->isAidlVhal()) {
+ // Skip checking timestamp for HIDL because the behavior for sample rate and timestamp is
+ // only specified clearly for AIDL.
+
+ // Timeout is 2 seconds, which gives a 1 second buffer.
+ ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(minSampleRate),
+ std::chrono::seconds(2)))
+ << "Didn't get enough events for subscribing to minSampleRate";
+ }
+
+ result = client->subscribe({{.propId = propId, .sampleRate = maxSampleRate}});
+
+ ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32
+ ", error: %s",
+ propId, result.error().message().c_str());
+
+ if (mVhalClient->isAidlVhal()) {
+ ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(maxSampleRate),
+ std::chrono::seconds(2)))
+ << "Didn't get enough events for subscribing to maxSampleRate";
+
+ std::unordered_set<int64_t> timestamps;
+ // Event event should have a different timestamp.
+ for (const int64_t& eventTimestamp : mCallback->getEventTimestamps(propId)) {
+ ASSERT_TRUE(timestamps.find(eventTimestamp) == timestamps.end())
+ << "two events for the same property must not have the same timestamp";
+ timestamps.insert(eventTimestamp);
+ }
+ }
result = client->unsubscribe({propId});
ASSERT_TRUE(result.ok()) << StringPrintf("Failed to unsubscribe to property: %" PRId32
@@ -325,6 +376,49 @@
kInvalidProp);
}
+// Test the timestamp returned in GetValues results is the timestamp when the value is retrieved.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetValuesTimestampAIDL) {
+ if (!mVhalClient->isAidlVhal()) {
+ GTEST_SKIP() << "Skip checking timestamp for HIDL because the behavior is only specified "
+ "for AIDL";
+ }
+
+ int32_t propId = toInt(VehicleProperty::PARKING_BRAKE_ON);
+ auto prop = mVhalClient->createHalPropValue(propId);
+
+ auto result = mVhalClient->getValueSync(*prop);
+
+ ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32
+ ", error: %s",
+ propId, result.error().message().c_str());
+ ASSERT_NE(result.value(), nullptr) << "Result value must not be null";
+ ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value";
+
+ bool parkBrakeOnValue1 = (result.value()->getInt32Values()[0] == 1);
+ int64_t timestampValue1 = result.value()->getTimestamp();
+
+ result = mVhalClient->getValueSync(*prop);
+
+ ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32
+ ", error: %s",
+ propId, result.error().message().c_str());
+ ASSERT_NE(result.value(), nullptr) << "Result value must not be null";
+ ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value";
+
+ bool parkBarkeOnValue2 = (result.value()->getInt32Values()[0] == 1);
+ int64_t timestampValue2 = result.value()->getTimestamp();
+
+ if (parkBarkeOnValue2 == parkBrakeOnValue1) {
+ ASSERT_EQ(timestampValue2, timestampValue1)
+ << "getValue result must contain a timestamp updated when the value was updated, if"
+ "the value does not change, expect the same timestamp";
+ } else {
+ ASSERT_GT(timestampValue2, timestampValue1)
+ << "getValue result must contain a timestamp updated when the value was updated, if"
+ "the value changes, expect the newer value has a larger timestamp";
+ }
+}
+
std::vector<ServiceDescriptor> getDescriptors() {
std::vector<ServiceDescriptor> descriptors;
for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {