Implement getSupportedValuesLists in DefaultVehicleHal.
Implement getSupportedValuesLists in DefaultVehicleHal. This CL
also updates the doc to allow per [propId, areaId] to still kept
HasSupportedValueInfo as null for new VHAL implementation. This allows
VHAL implementation to opt-in the new supported values API on a
per [propId, areaId] basis.
Flag: EXEMPT HAL impl
Test: atest DefaultVehicleHalTest
Bug: 382563296
Change-Id: I931fe18c2e326c46446033204e8fdf63d5c10c8a
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
index 220b1da..96c4953 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -267,6 +267,9 @@
/**
* Gets the supported values lists for [propId, areaId]s.
*
+ * This is only supported for [propId, areaId]s that have non-null
+ * {@code hasSupportedValueInfo} for their {@code VehicleAreaConfig}.
+ *
* For a specific [propId, areaId], if the hardware currently specifies
* a list of supported values for it, then it is returned through the
* {@code supportedValuesList} field inside
@@ -304,6 +307,9 @@
/**
* Gets the min/max supported values for [propId, areaId]s.
*
+ * This is only supported for [propId, areaId]s that have non-null
+ * {@code hasSupportedValueInfo} for their {@code VehicleAreaConfig}.
+ *
* For a specific [propId, areaId], if the hardware currently specifies
* min/max supported value for it, then it is returned through the
* {@code minSupportedValue} or {@code maxSupportedValue} field inside
@@ -342,6 +348,9 @@
/**
* Registers the supported value change callback.
*
+ * This is only supported for [propId, areaId]s that have non-null
+ * {@code hasSupportedValueInfo} for their {@code VehicleAreaConfig}.
+ *
* For the specified [propId, areaId]s,
* {@code callback.onSupportedValueChange} must be invoked if change
* happens.
@@ -360,6 +369,9 @@
/**
* Unregisters the supported value change callback.
*
+ * This is only supported for [propId, areaId]s that have non-null
+ * {@code hasSupportedValueInfo} for their {@code VehicleAreaConfig}.
+ *
* @param callback The callback to unregister.
* @param propIdAreaIds A list of [propId, areaId]s to unregister.
*/
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
index f85ad3a..a3508ee 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
@@ -43,6 +43,8 @@
*
* If the [propId, areaId] does not specify a max supported value, this
* is {@code null}.
+ *
+ * This must be ignored if status is not {@code StatusCode.OK}.
*/
@nullable RawPropValues maxSupportedValue;
}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
index 4524f4f..8800b0b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
@@ -36,6 +36,8 @@
*
* If the [propId, areaId] does not specify a supported values list, this
* is {@code null}.
+ *
+ * This must be ignored if status is not {@code StatusCode.OK}.
*/
@nullable List<RawPropValues> supportedValuesList;
}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 62d7e21..c6b8cd1 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -230,10 +230,17 @@
boolean supportVariableUpdateRate;
/**
- * For VHAL implementation >= V4, this must not be {@code null}. This specifies whether
- * this property may have min/max supported value or supported values list.
+ * This specifies whether this property may have min/max supported value or supported values
+ * list for [propId, areaId] that supports new supported values APIs.
*
- * For VHAL implementation < V4, this is always {@code null} and is not accessed.
+ * If this is not {@code null}. The client may use {@code getMinMaxSupportedValue},
+ * {@code getSupportedValuesLists}, {@code subscribeSupportedValueChange},
+ * {@code unsubscribeSupportedValueChange}.
+ *
+ * If this is {@code null} for legacy properties, the APIs mentioned before are not supported.
+ * Client must fallback to use static supported value information in {@code VehicleAreaConfig}.
+ *
+ * For VHAL implementation < V4, this is always {@code null}.
*/
@nullable HasSupportedValueInfo hasSupportedValueInfo;
}
diff --git a/automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h
index 0684655..f46a1c8 100644
--- a/automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h
@@ -18,9 +18,11 @@
#define android_hardware_automotive_vehicle_aidl_impl_hardware_include_IVehicleHardware_H_
#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
#include <memory>
#include <optional>
+#include <unordered_set>
#include <vector>
namespace android {
@@ -59,10 +61,23 @@
using GetValuesCallback = std::function<void(std::vector<aidlvhal::GetValueResult>)>;
using PropertyChangeCallback = std::function<void(std::vector<aidlvhal::VehiclePropValue>)>;
using PropertySetErrorCallback = std::function<void(std::vector<SetValueErrorEvent>)>;
+ using SupportedValueChangeCallback = std::function<void(std::vector<PropIdAreaId>)>;
virtual ~IVehicleHardware() = default;
// Get all the property configs.
+ //
+ // Note that {@code VehicleAreaConfig.HasSupportedValueInfo} field is newly introduced in VHAL
+ // V4 to specify whether the [propertyId, areaId] has specified min/max supported value or
+ // supported values list.
+ //
+ // Since IVehicleHardware is designed to be backward compatible, this field can be set to null.
+ // If this field is set to null, VHAL client should fallback to use min/max supported value
+ // information in {@code VehicleAreaConfig} and {@code supportedEnumVaules} for enum properties.
+ //
+ // It is highly recommended to specify {@code VehicleAreaConfig.HasSupportedValueInfo} for new
+ // property implementations, even if the property does not specify supported values or the
+ // supported values are static.
virtual std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const = 0;
// Get the property configs for the specified propId. This is used for early-boot
@@ -240,6 +255,76 @@
[[maybe_unused]] float sampleRate) {
return aidlvhal::StatusCode::OK;
}
+
+ // Gets the min/max supported values for each of the specified [propId, areaId]s.
+ //
+ // The returned result may change dynamically.
+ //
+ // This is only called for [propId, areaId] that has
+ // {@code HasSupportedValueInfo.hasMinSupportedValue} or
+ // {@code HasSupportedValueInfo.hasMinSupportedValue} set to true.
+ //
+ // Client must implement (override) this function if at least one [propId, areaId]'s
+ // {@code HasSupportedValueInfo} is not null.
+ virtual std::vector<aidlvhal::MinMaxSupportedValueResult> getMinMaxSupportedValues(
+ [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) {
+ return {};
+ }
+
+ // Gets the supported values list for each of the specified [propId, areaId]s.
+ //
+ // The returned result may change dynamically.
+ //
+ // This is only called for [propId, areaId] that has
+ // {@code HasSupportedValueInfo.hasSupportedValuesList} set to true.
+ //
+ // Client must implement (override) this function if at least one [propId, areaId]'s
+ // {@code HasSupportedValueInfo} is not null.
+ virtual std::vector<aidlvhal::SupportedValuesListResult> getSupportedValuesLists(
+ [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) {
+ return {};
+ }
+
+ // Register a callback that would be called when the min/max supported value or supported
+ // values list change dynamically for propertyID returned from
+ // getPropertyIdsThatImplementGetSupportedValue
+ //
+ // This function must only be called once during initialization.
+ //
+ // Client must implement (override) this function if at least one [propId, areaId]'s
+ // {@code HasSupportedValueInfo} is not null.
+ virtual void registerSupportedValueChangeCallback(
+ [[maybe_unused]] std::unique_ptr<const SupportedValueChangeCallback> callback) {
+ // Do nothing.
+ }
+
+ // Subscribes to the min/max supported value or supported values list change for the specified
+ // [propId, areaId]s.
+ //
+ // If the propertyId's supported values are static, then must do nothing.
+ //
+ // This is only called for [propId, areaId] that has non-null {@code HasSupportedValueInfo}.
+ //
+ // Client must implement (override) this function if at least one [propId, areaId]'s
+ // {@code HasSupportedValueInfo} is not null.
+ virtual aidlvhal::StatusCode subscribeSupportedValueChange(
+ [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) {
+ return aidlvhal::StatusCode::OK;
+ }
+
+ // Unsubscrbies to the min/max supported value or supported values list change.
+ //
+ // Must do nothing if the [propId, areaId] was not previously subscribed to for supported
+ // values change.
+ //
+ // This is only called for [propId, areaId] that has non-null {@code HasSupportedValueInfo}.
+ //
+ // Client must implement (override) this function if at least one [propId, areaId]'s
+ // {@code HasSupportedValueInfo} is not null.
+ virtual aidlvhal::StatusCode unsubscribeSupportedValueChange(
+ [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) {
+ return aidlvhal::StatusCode::OK;
+ }
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h
index 4fa0a06..fcc006b 100644
--- a/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h
@@ -53,6 +53,8 @@
#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
#include <aidl/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.h>
#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -65,6 +67,8 @@
#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
#include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
+#include <aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.h>
+#include <aidl/android/hardware/automotive/vehicle/SupportedValuesListResults.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAirbagLocation.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
diff --git a/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
index 5d64e6f..8785bcd 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
@@ -233,6 +233,10 @@
std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
callback) const EXCLUDES(mConfigLock);
+ android::base::Result<const aidlvhal::VehicleAreaConfig*> getAreaConfigForPropIdAreaId(
+ int32_t propId, int32_t areaId) const;
+ android::base::Result<const aidlvhal::HasSupportedValueInfo*> getHasSupportedValueInfo(
+ int32_t propId, int32_t areaId) const;
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue,
diff --git a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
index 1e55a1a..3edd651 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
@@ -49,6 +49,7 @@
using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::HasSupportedValueInfo;
using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResults;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
@@ -57,6 +58,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult;
using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResults;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
@@ -77,6 +79,11 @@
using ::ndk::ScopedAStatus;
using ::ndk::ScopedFileDescriptor;
+using VhalPropIdAreaId = ::aidl::android::hardware::automotive::vehicle::PropIdAreaId;
+
+#define propIdtoString(PROP_ID) \
+ aidl::android::hardware::automotive::vehicle::toString(static_cast<VehicleProperty>(PROP_ID))
+
std::string toString(const std::unordered_set<int64_t>& values) {
std::string str = "";
for (auto it = values.begin(); it != values.end(); it++) {
@@ -964,30 +971,114 @@
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::getSupportedValuesLists(
- const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
- SupportedValuesListResults*) {
- // TODO(b/381020465): Add relevant implementation.
- return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+Result<const VehicleAreaConfig*> DefaultVehicleHal::getAreaConfigForPropIdAreaId(
+ int32_t propId, int32_t areaId) const {
+ auto result = getConfig(propId);
+ if (!result.ok()) {
+ return Error() << "Failed to get property config for propertyId: " << propIdtoString(propId)
+ << ", error: " << result.error();
+ }
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(propId, areaId, config);
+ if (areaConfig == nullptr) {
+ return Error() << "AreaId config not found for propertyId: " << propIdtoString(propId)
+ << ", areaId: " << areaId;
+ }
+ return areaConfig;
}
-ScopedAStatus DefaultVehicleHal::getMinMaxSupportedValue(
- const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
- MinMaxSupportedValueResults*) {
+Result<const HasSupportedValueInfo*> DefaultVehicleHal::getHasSupportedValueInfo(
+ int32_t propId, int32_t areaId) const {
+ Result<const VehicleAreaConfig*> propIdAreaIdConfigResult =
+ getAreaConfigForPropIdAreaId(propId, areaId);
+ if (!isGlobalProp(propId) && !propIdAreaIdConfigResult.ok()) {
+ // For global property, it is possible that no config exists.
+ return Error() << propIdAreaIdConfigResult.error();
+ }
+ if (propIdAreaIdConfigResult.has_value()) {
+ auto areaConfig = propIdAreaIdConfigResult.value();
+ if (areaConfig->hasSupportedValueInfo.has_value()) {
+ return &(areaConfig->hasSupportedValueInfo.value());
+ }
+ }
+ return Error() << "property: " << propIdtoString(propId) << ", areaId: " << areaId
+ << " does not support this operation because hasSupportedValueInfo is null";
+}
+
+ScopedAStatus DefaultVehicleHal::getSupportedValuesLists(
+ const std::vector<VhalPropIdAreaId>& vhalPropIdAreaIds,
+ SupportedValuesListResults* supportedValuesListResults) {
+ std::vector<size_t> toHardwareRequestCounters;
+ std::vector<PropIdAreaId> toHardwarePropIdAreaIds;
+ std::vector<SupportedValuesListResult> results;
+ results.resize(vhalPropIdAreaIds.size());
+ for (size_t requestCounter = 0; requestCounter < vhalPropIdAreaIds.size(); requestCounter++) {
+ const auto& vhalPropIdAreaId = vhalPropIdAreaIds.at(requestCounter);
+ int32_t propId = vhalPropIdAreaId.propId;
+ int32_t areaId = vhalPropIdAreaId.areaId;
+ auto hasSupportedValueInfoResult = getHasSupportedValueInfo(propId, areaId);
+ if (!hasSupportedValueInfoResult.ok()) {
+ ALOGE("getSupportedValuesLists: %s",
+ hasSupportedValueInfoResult.error().message().c_str());
+ results[requestCounter] = SupportedValuesListResult{
+ .status = StatusCode::INVALID_ARG, .supportedValuesList = std::nullopt};
+ continue;
+ }
+
+ const auto& hasSupportedValueInfo = *(hasSupportedValueInfoResult.value());
+ if (hasSupportedValueInfo.hasSupportedValuesList) {
+ toHardwarePropIdAreaIds.push_back(PropIdAreaId{.propId = propId, .areaId = areaId});
+ toHardwareRequestCounters.push_back(requestCounter);
+ } else {
+ results[requestCounter] = SupportedValuesListResult{
+ .status = StatusCode::OK, .supportedValuesList = std::nullopt};
+ continue;
+ }
+ }
+ if (toHardwarePropIdAreaIds.size() != 0) {
+ std::vector<SupportedValuesListResult> resultsFromHardware =
+ mVehicleHardware->getSupportedValuesLists(toHardwarePropIdAreaIds);
+ // It is guaranteed that toHardwarePropIdAreaIds, toHardwareRequestCounters,
+ // resultsFromHardware have the same size.
+ if (resultsFromHardware.size() != toHardwareRequestCounters.size()) {
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(StatusCode::INTERNAL_ERROR),
+ fmt::format(
+ "getSupportedValuesLists: Unexpected results size from IVehicleHardware"
+ ", got: {}, expect: {}",
+ resultsFromHardware.size(), toHardwareRequestCounters.size())
+ .c_str());
+ }
+ for (size_t i = 0; i < toHardwareRequestCounters.size(); i++) {
+ results[toHardwareRequestCounters[i]] = resultsFromHardware[i];
+ }
+ }
+ ScopedAStatus status =
+ vectorToStableLargeParcelable(std::move(results), supportedValuesListResults);
+ if (!status.isOk()) {
+ int statusCode = status.getServiceSpecificError();
+ ALOGE("getSupportedValuesLists: failed to marshal result into large parcelable, error: "
+ "%s, code: %d",
+ status.getMessage(), statusCode);
+ return status;
+ }
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus DefaultVehicleHal::getMinMaxSupportedValue(const std::vector<VhalPropIdAreaId>&,
+ MinMaxSupportedValueResults*) {
// TODO(b/381020465): Add relevant implementation.
return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ScopedAStatus DefaultVehicleHal::registerSupportedValueChangeCallback(
- const std::shared_ptr<IVehicleCallback>&,
- const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&) {
+ const std::shared_ptr<IVehicleCallback>&, const std::vector<VhalPropIdAreaId>&) {
// TODO(b/381020465): Add relevant implementation.
return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ScopedAStatus DefaultVehicleHal::unregisterSupportedValueChangeCallback(
- const std::shared_ptr<IVehicleCallback>&,
- const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&) {
+ const std::shared_ptr<IVehicleCallback>&, const std::vector<VhalPropIdAreaId>&) {
// TODO(b/381020465): Add relevant implementation.
return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
index ad34a4c..50bd8e0 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
@@ -21,6 +21,7 @@
#include <IVehicleHardware.h>
#include <LargeParcelableBase.h>
+#include <aidl/android/hardware/automotive/vehicle/HasSupportedValueInfo.h>
#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
@@ -51,14 +52,18 @@
using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::HasSupportedValueInfo;
using ::aidl::android::hardware::automotive::vehicle::IVehicle;
using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult;
+using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResults;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
@@ -85,6 +90,8 @@
using ::testing::UnorderedElementsAreArray;
using ::testing::WhenSortedBy;
+using VhalPropIdAreaId = ::aidl::android::hardware::automotive::vehicle::PropIdAreaId;
+
constexpr int32_t INVALID_PROP_ID = 0;
// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x20000000 + 0x03000000 + 0x00400000;
@@ -112,6 +119,11 @@
return static_cast<int32_t>(i) + 0x20000000 + 0x01000000 + 0x00410000;
}
+int32_t testInt32VecWindowProp(size_t i) {
+ // VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32_VEC
+ return static_cast<int32_t>(i) + 0x20000000 + 0x03000000 + 0x00410000;
+}
+
std::string toString(const std::vector<SubscribeOptions>& options) {
std::string optionsStr;
for (const auto& option : options) {
@@ -2121,6 +2133,144 @@
}
}
+TEST_F(DefaultVehicleHalTest, testGetSupportedValuesLists) {
+ auto testConfigs = std::vector<VehiclePropConfig>(
+ {// This ia valid request, but no supported values are specified.
+ VehiclePropConfig{
+ .prop = testInt32VecProp(1),
+ .areaConfigs =
+ {
+ {.areaId = 0,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasSupportedValuesList = false,
+ }},
+ },
+ },
+ // This is an invalid request since hasSupportedValueInfo is null. This is not
+ // supported.
+ VehiclePropConfig{
+ .prop = testInt32VecWindowProp(2),
+ .areaConfigs =
+ {
+ {
+ .areaId = 2,
+ },
+ },
+ },
+ // This is an invalid request for global property.
+ VehiclePropConfig{
+ .prop = testInt32VecProp(3),
+ },
+ // This is a normal request.
+ VehiclePropConfig{
+ .prop = testInt32VecWindowProp(4),
+ .areaConfigs =
+ {
+ {.areaId = 4,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasSupportedValuesList = true,
+ }},
+ },
+ }});
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ MockVehicleHardware* hardwarePtr = hardware.get();
+ hardware->setPropertyConfigs(testConfigs);
+
+ SupportedValuesListResult resultFromHardware = {
+ .status = StatusCode::OK,
+ .supportedValuesList =
+ std::vector<std::optional<RawPropValues>>{RawPropValues{.int32Values = {1}}}};
+ auto response = std::vector<SupportedValuesListResult>({resultFromHardware});
+ hardware->setSupportedValuesListResponse(response);
+
+ auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ SupportedValuesListResults results;
+
+ auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
+ auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
+ auto propIdAreaId3 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(3), .areaId = 0};
+ auto propIdAreaId4 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4};
+ auto status = vhal->getSupportedValuesLists(
+ std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2, propIdAreaId3,
+ propIdAreaId4},
+ &results);
+
+ ASSERT_TRUE(status.isOk()) << "Get non-okay status from getSupportedValuesLists"
+ << status.getMessage();
+ ASSERT_THAT(hardwarePtr->getSupportedValuesListRequest(),
+ ElementsAre(PropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4}))
+ << "Only valid request 4 should get to hardware";
+
+ ASSERT_EQ(results.payloads.size(), 4u);
+ SupportedValuesListResult result = results.payloads[0];
+ ASSERT_EQ(result.status, StatusCode::OK)
+ << "Must return OK even if the supported values list is not specified";
+ ASSERT_FALSE(result.supportedValuesList.has_value())
+ << "Must return an empty supported values list if not specified";
+
+ result = results.payloads[1];
+ ASSERT_EQ(result.status, StatusCode::INVALID_ARG)
+ << "PropId, areaId that set hasSupportedValueInfo to null must not be supported";
+ ASSERT_FALSE(result.supportedValuesList.has_value());
+
+ result = results.payloads[2];
+ ASSERT_EQ(result.status, StatusCode::INVALID_ARG)
+ << "PropId, areaId that set hasSupportedValueInfo to null must not be supported";
+ ASSERT_FALSE(result.supportedValuesList.has_value());
+
+ result = results.payloads[3];
+ ASSERT_EQ(result.status, StatusCode::OK);
+ ASSERT_TRUE(result.supportedValuesList.has_value());
+ ASSERT_EQ(result.supportedValuesList.value().size(), 1u);
+ ASSERT_EQ(result.supportedValuesList.value()[0]->int32Values.size(), 1u);
+ ASSERT_EQ((result.supportedValuesList.value())[0]->int32Values[0], 1);
+}
+
+TEST_F(DefaultVehicleHalTest, testGetSupportedValuesLists_propIdAreaIdNotFound) {
+ auto testConfigs = std::vector<VehiclePropConfig>({
+ VehiclePropConfig{
+ .prop = testInt32VecWindowProp(1),
+ .areaConfigs =
+ {
+ {.areaId = 1,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasSupportedValuesList = true,
+ }},
+ },
+ },
+ });
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ hardware->setPropertyConfigs(testConfigs);
+
+ auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ SupportedValuesListResults results;
+
+ // propId not valid.
+ auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 1};
+ // areaId not valid.
+ auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(1), .areaId = 2};
+
+ auto status = vhal->getSupportedValuesLists(
+ std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2}, &results);
+
+ ASSERT_TRUE(status.isOk()) << "Get non-okay status from getSupportedValuesLists"
+ << status.getMessage();
+ ASSERT_EQ(results.payloads.size(), 2u);
+ SupportedValuesListResult result = results.payloads[0];
+ ASSERT_EQ(result.status, StatusCode::INVALID_ARG);
+ result = results.payloads[1];
+ ASSERT_EQ(result.status, StatusCode::INVALID_ARG);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
index e796ce5..ed5f47c 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
@@ -30,6 +30,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
@@ -200,6 +201,13 @@
return propIdAreaIds;
}
+std::vector<SupportedValuesListResult> MockVehicleHardware::getSupportedValuesLists(
+ const std::vector<PropIdAreaId>& propIdAreaIds) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSupportedValuesListRequest = propIdAreaIds;
+ return mSupportedValuesListResponse;
+}
+
void MockVehicleHardware::registerOnPropertyChangeEvent(
std::unique_ptr<const PropertyChangeCallback> callback) {
std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -267,6 +275,17 @@
mEventBatchingWindow = window;
}
+void MockVehicleHardware::setSupportedValuesListResponse(
+ const std::vector<SupportedValuesListResult>& response) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSupportedValuesListResponse = response;
+}
+
+std::vector<PropIdAreaId> MockVehicleHardware::getSupportedValuesListRequest() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mSupportedValuesListRequest;
+}
+
std::chrono::nanoseconds MockVehicleHardware::getPropertyOnChangeEventBatchingWindow() {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mEventBatchingWindow;
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
index 06e01a8..4b2ca7c 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
@@ -67,6 +67,8 @@
aidl::android::hardware::automotive::vehicle::StatusCode unsubscribe(int32_t propId,
int32_t areaId) override;
std::chrono::nanoseconds getPropertyOnChangeEventBatchingWindow() override;
+ std::vector<aidl::android::hardware::automotive::vehicle::SupportedValuesListResult>
+ getSupportedValuesLists(const std::vector<PropIdAreaId>& propIdAreaIds) override;
// Test functions.
void setPropertyConfigs(
@@ -78,6 +80,10 @@
void addSetValueResponses(
const std::vector<aidl::android::hardware::automotive::vehicle::SetValueResult>&
responses);
+ void setSupportedValuesListResponse(
+ const std::vector<
+ aidl::android::hardware::automotive::vehicle::SupportedValuesListResult>&
+ response);
void setGetValueResponder(
std::function<aidl::android::hardware::automotive::vehicle::StatusCode(
std::shared_ptr<const GetValuesCallback>,
@@ -88,6 +94,7 @@
nextGetValueRequests();
std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>
nextSetValueRequests();
+ std::vector<PropIdAreaId> getSupportedValuesListRequest();
void setStatus(const char* functionName,
aidl::android::hardware::automotive::vehicle::StatusCode status);
void setSleepTime(int64_t timeInNano);
@@ -118,6 +125,9 @@
mSetValueRequests GUARDED_BY(mLock);
mutable std::list<std::vector<aidl::android::hardware::automotive::vehicle::SetValueResult>>
mSetValueResponses GUARDED_BY(mLock);
+ mutable std::vector<PropIdAreaId> mSupportedValuesListRequest GUARDED_BY(mLock);
+ mutable std::vector<aidl::android::hardware::automotive::vehicle::SupportedValuesListResult>
+ mSupportedValuesListResponse GUARDED_BY(mLock);
std::unordered_map<const char*, aidl::android::hardware::automotive::vehicle::StatusCode>
mStatusByFunctions GUARDED_BY(mLock);
int64_t mSleepTime GUARDED_BY(mLock) = 0;