Add set supported value debug command.
Add debug command to ref VHAL to allow setting min/max value and
supported values list for the test vendor property. The command
also triggers supported value change event so that we can test
the subscription logic.
Flag: EXEMPT HAL change
Test: atest FakeVehicleHardwareTest
Manual test using KS, verify we see the supported value change event.
Bug: 382563296
Change-Id: I7ec791b1ee8e6cade4e267b55e4b58e1d3a9e49c
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
index b7ada62..e20befc 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -100,6 +100,9 @@
void registerOnPropertySetErrorEvent(
std::unique_ptr<const PropertySetErrorCallback> callback) override;
+ void registerSupportedValueChangeCallback(
+ std::unique_ptr<const SupportedValueChangeCallback> callback) override;
+
// Subscribe to a new [propId, areaId] or change the update rate.
aidl::android::hardware::automotive::vehicle::StatusCode subscribe(
aidl::android::hardware::automotive::vehicle::SubscribeOptions options) override;
@@ -177,6 +180,7 @@
// Only allowed to set once.
std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback;
std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
+ std::unique_ptr<const SupportedValueChangeCallback> mOnSupportedValueChangeCallback;
std::mutex mLock;
std::unordered_map<PropIdAreaId, RefreshInfo, PropIdAreaIdHash> mRefreshInfoByPropIdAreaId
@@ -185,6 +189,10 @@
std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
mSavedProps GUARDED_BY(mLock);
std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
+ int32_t mMinSupportedValueForTestIntProp GUARDED_BY(mLock) = 0;
+ int32_t mMaxSupportedValueForTestIntProp GUARDED_BY(mLock) = 10;
+ std::vector<int32_t> mSupportedValuesListForTestIntProp GUARDED_BY(mLock) = {0, 2, 4, 6, 8, 10};
+
// PendingRequestHandler is thread-safe.
mutable PendingRequestHandler<GetValuesCallback,
aidl::android::hardware::automotive::vehicle::GetValueRequest>
@@ -281,6 +289,8 @@
std::string dumpRestoreProperty(const std::vector<std::string>& options);
std::string dumpInjectEvent(const std::vector<std::string>& options);
std::string dumpSubscriptions();
+ std::string dumpSetSupportedValues(const std::vector<std::string>& options);
+ std::string dumpSetMinMaxValue(const std::vector<std::string>& options);
std::vector<std::string> getOptionValues(const std::vector<std::string>& options,
size_t* index);
@@ -310,6 +320,9 @@
float sampleRateHz) REQUIRES(mLock);
void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
+ void triggerSupportedValueChange(
+ const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config)
+ EXCLUDES(mLock);
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
index f1aaefc..01e40fb 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -73,6 +73,7 @@
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
@@ -1372,6 +1373,10 @@
result.buffer = "successfully restored vendor configs";
} else if (EqualsIgnoreCase(option, "--dumpSub")) {
result.buffer = dumpSubscriptions();
+ } else if (EqualsIgnoreCase(option, "--set-minmaxvalue")) {
+ result.buffer = dumpSetMinMaxValue(options);
+ } else if (EqualsIgnoreCase(option, "--set-supportedvalues")) {
+ result.buffer = dumpSetSupportedValues(options);
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
@@ -1794,6 +1799,88 @@
return result;
}
+std::string FakeVehicleHardware::dumpSetMinMaxValue(const std::vector<std::string>& options) {
+ if (auto result = checkArgumentsSize(options, /*minSize=*/3); !result.ok()) {
+ return getErrorMsg(result);
+ }
+ int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
+ auto configResult = mServerSidePropStore->getPropConfig(testPropId);
+ if (!configResult.ok()) {
+ return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
+ }
+ int32_t values[2];
+ for (size_t i = 1; i < 3; i++) {
+ auto int32Result = safelyParseInt<int32_t>(i, options[i]);
+ if (!int32Result.ok()) {
+ return StringPrintf(
+ "Failed to set min/max supported value: Value: \"%s\" is not a valid int: %s\n",
+ options[i].c_str(), getErrorMsg(int32Result).c_str());
+ }
+ values[i - 1] = int32Result.value();
+ }
+ int32_t minValue = values[0];
+ int32_t maxValue = values[1];
+ if (minValue > maxValue) {
+ return StringPrintf("Failed to set min/max supported value: MinValue: %" PRId32
+ " must not > MaxValue: %" PRId32,
+ minValue, maxValue);
+ }
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mMinSupportedValueForTestIntProp = minValue;
+ mMaxSupportedValueForTestIntProp = maxValue;
+ }
+ triggerSupportedValueChange(configResult.value());
+ return "Min/Max supported value for VENDOR_EXTENSION_INT_PROPERTY set";
+}
+
+std::string FakeVehicleHardware::dumpSetSupportedValues(const std::vector<std::string>& options) {
+ if (auto result = checkArgumentsSize(options, /*minSize=*/2); !result.ok()) {
+ return getErrorMsg(result);
+ }
+ int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
+ auto configResult = mServerSidePropStore->getPropConfig(testPropId);
+ if (!configResult.ok()) {
+ return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
+ }
+ std::vector<int32_t> values;
+ for (size_t i = 1; i < options.size(); i++) {
+ auto int32Result = safelyParseInt<int32_t>(i, options[i]);
+ if (!int32Result.ok()) {
+ return StringPrintf(
+ "Failed to set supported values: Value: \"%s\" is not a valid int: %s\n",
+ options[i].c_str(), getErrorMsg(int32Result).c_str());
+ }
+ values.push_back(int32Result.value());
+ }
+
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSupportedValuesListForTestIntProp = values;
+ }
+ triggerSupportedValueChange(configResult.value());
+ return "Supported values list for VENDOR_EXTENSION_INT_PROPERTY set";
+}
+
+// Triggers supported value change for all areaIds that specify hasSupportedValueInfo.
+void FakeVehicleHardware::triggerSupportedValueChange(const VehiclePropConfig& config) {
+ if (mOnSupportedValueChangeCallback == nullptr) {
+ ALOGE("onSupportedValueChangeCallback is not registered, ignore event");
+ return;
+ }
+
+ std::vector<PropIdAreaId> propIdAreaIds;
+ for (const VehicleAreaConfig& areaConfig : config.areaConfigs) {
+ if (areaConfig.hasSupportedValueInfo != std::nullopt) {
+ propIdAreaIds.push_back({
+ .propId = config.prop,
+ .areaId = areaConfig.areaId,
+ });
+ }
+ }
+ (*mOnSupportedValueChangeCallback)(std::move(propIdAreaIds));
+}
+
std::string FakeVehicleHardware::dumpHelp() {
return "Usage: \n\n"
"[no args]: dumps (id and value) all supported properties \n"
@@ -1805,6 +1892,10 @@
"The value arguments constructs a VehiclePropValue used in the getValue request. \n"
"--set <PROP_ID> [ValueArguments]: sets the value of property PROP_ID, the value "
"arguments constructs a VehiclePropValue used in the setValue request. \n"
+ "--set-minmaxvalue <MIN_VALUE(int)> <MAX_VALUE(int)>: sets the min max supported value "
+ "for VENDOR_EXTENSION_INT_PROPERTY\n"
+ "--set-supportedvalues <VALUE_1(int)> [VALUE_2(int) ...]: sets the supported values list"
+ "for VENDOR_EXTENSION_INT_PROPERTY\n"
"--save-prop <PROP_ID> [-a AREA_ID]: saves the current value for PROP_ID, integration "
"tests that modify prop value must call this before test and restore-prop after test. \n"
"--restore-prop <PROP_ID> [-a AREA_ID]: restores a previously saved property value. \n"
@@ -2280,6 +2371,15 @@
mOnPropertySetErrorCallback = std::move(callback);
}
+void FakeVehicleHardware::registerSupportedValueChangeCallback(
+ std::unique_ptr<const SupportedValueChangeCallback> callback) {
+ if (mOnSupportedValueChangeCallback != nullptr) {
+ ALOGE("registerOnPropertyChangeEvent must only be called once");
+ return;
+ }
+ mOnSupportedValueChangeCallback = std::move(callback);
+}
+
StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
int32_t propId = options.propId;
@@ -2303,6 +2403,7 @@
std::vector<MinMaxSupportedValueResult> FakeVehicleHardware::getMinMaxSupportedValues(
const std::vector<PropIdAreaId>& propIdAreaIds) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
std::vector<MinMaxSupportedValueResult> results;
// We only support VENDOR_EXTENSION_INT_PROPERTY
for (const auto& propIdAreaId : propIdAreaIds) {
@@ -2318,11 +2419,11 @@
.status = StatusCode::OK,
.minSupportedValue =
RawPropValues{
- .int32Values = {0},
+ .int32Values = {mMinSupportedValueForTestIntProp},
},
.maxSupportedValue =
RawPropValues{
- .int32Values = {10},
+ .int32Values = {mMaxSupportedValueForTestIntProp},
},
});
}
@@ -2331,6 +2432,7 @@
std::vector<SupportedValuesListResult> FakeVehicleHardware::getSupportedValuesLists(
const std::vector<PropIdAreaId>& propIdAreaIds) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
std::vector<SupportedValuesListResult> results;
// We only support VENDOR_EXTENSION_INT_PROPERTY
for (const auto& propIdAreaId : propIdAreaIds) {
@@ -2342,16 +2444,13 @@
});
continue;
}
+ std::vector<std::optional<RawPropValues>> supportedValuesList;
+ for (int32_t value : mSupportedValuesListForTestIntProp) {
+ supportedValuesList.push_back(RawPropValues{.int32Values = {value}});
+ }
results.push_back(SupportedValuesListResult{
.status = StatusCode::OK,
- .supportedValuesList = std::vector<std::optional<RawPropValues>>({
- RawPropValues{.int32Values = {0}},
- RawPropValues{.int32Values = {2}},
- RawPropValues{.int32Values = {4}},
- RawPropValues{.int32Values = {6}},
- RawPropValues{.int32Values = {8}},
- RawPropValues{.int32Values = {10}},
- }),
+ .supportedValuesList = supportedValuesList,
});
}
return results;
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 29a690b..a097135 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -2759,6 +2759,86 @@
"response\nNo SetUserIdentificationAssociation response\n"));
}
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue) {
+ std::vector<std::string> options = {"--set-minmaxvalue", "1", "100"};
+ std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+ getHardware()->registerSupportedValueChangeCallback(
+ std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+ [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+ changedPropIdAreaIds = propIdAreaIds;
+ }));
+
+ DumpResult result = getHardware()->dump(options);
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, ContainsRegex("Min/Max supported value .* set"));
+
+ ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+
+ auto results = getHardware()->getMinMaxSupportedValues({PropIdAreaId{
+ .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});
+
+ ASSERT_EQ(results.size(), 1u);
+ EXPECT_EQ(results[0].status, StatusCode::OK);
+ EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.int32Values = {1}});
+ EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {100}});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_invalidInt) {
+ std::vector<std::string> options = {"--set-minmaxvalue", "abc", "100"};
+
+ DumpResult result = getHardware()->dump(options);
+ ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+
+ options = {"--set-minmaxvalue", "1", "abc"};
+
+ result = getHardware()->dump(options);
+ ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_minLargerThanMax) {
+ std::vector<std::string> options = {"--set-minmaxvalue", "2", "1"};
+
+ DumpResult result = getHardware()->dump(options);
+ ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues) {
+ std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "3"};
+ std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+ getHardware()->registerSupportedValueChangeCallback(
+ std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+ [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+ changedPropIdAreaIds = propIdAreaIds;
+ }));
+
+ DumpResult result = getHardware()->dump(options);
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, ContainsRegex("Supported values list .* set"));
+
+ ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+
+ auto results = getHardware()->getSupportedValuesLists({PropIdAreaId{
+ .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});
+
+ ASSERT_EQ(results.size(), 1u);
+ EXPECT_EQ(results[0].status, StatusCode::OK);
+ EXPECT_NE(results[0].supportedValuesList, std::nullopt);
+ EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
+ RawPropValues{.int32Values = {1}},
+ RawPropValues{.int32Values = {2}},
+ RawPropValues{.int32Values = {3}},
+ }));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_invalidInt) {
+ std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "ab", "3"};
+
+ DumpResult result = getHardware()->dump(options);
+ ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+}
+
struct SetPropTestCase {
std::string test_name;
std::vector<std::string> options;