Merge changes I0ccae57b,I40965f38 into main
* changes:
Add sound parameter validation in media quality VTS
Add picture parameter validation in media quality VTS
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
index 220b1da..cdf9066 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -237,6 +237,8 @@
* {@link StatusCode#INVALID_ARG}. If a specified propId was not subscribed
* before, this method must ignore that propId.
*
+ * Unsubscribe a not-subscribed property ID must do nothing.
+ *
* If error is returned, some of the properties failed to unsubscribe.
* Caller is safe to try again, since unsubscribing an already unsubscribed
* property is okay.
@@ -267,6 +269,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 +309,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 +350,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 +371,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/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index 6cd7d1f..b774580 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -385,7 +385,7 @@
{
"name": "Fan speed setting",
"value": 356517120,
- "description": "Fan speed setting\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the lowest fan speed. The maxInt32Value indicates the highest fan speed.\nThis property is not in any particular unit but in a specified range of relative speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+ "description": "Fan speed setting\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the lowest fan speed. The maxInt32Value indicates the highest fan speed.\nIf {@code HasSupportedValueInfo} for a specific area ID is not {@code null}:\n{@code HasSupportedValueInfo.hasMinSupportedValue} and {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for the specific area ID.\n{@code MinMaxSupportedValueResult.minSupportedValue} indicates the lowest fan speed.\n{@code MinMaxSupportedValueResult.maxSupportedValue} indicates the highest fan speed.\nAll integers between minSupportedValue and maxSupportedValue must be supported.\nAt boot, minInt32Value is equal to minSupportedValue, maxInt32Value is equal to maxSupportedValue.\n\nThis property is not in any particular unit but in a specified range of relative speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
},
{
"name": "Fan direction setting",
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/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleUtils.h
index 90a7c46..5b19100 100644
--- a/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleUtils.h
@@ -310,6 +310,12 @@
return toScopedAStatus(result, getErrorCode(result), additionalErrorMsg);
}
+// This is for debug purpose only.
+inline std::string propIdToString(int32_t propId) {
+ return toString(
+ static_cast<aidl::android::hardware::automotive::vehicle::VehicleProperty>(propId));
+}
+
struct PropIdAreaId {
int32_t propId;
int32_t areaId;
@@ -317,6 +323,11 @@
inline bool operator==(const PropIdAreaId& other) const {
return areaId == other.areaId && propId == other.propId;
}
+
+ // This is for debug purpose only.
+ inline std::string toString() const {
+ return fmt::format("{{propId: {}, areaId: {}}}", propIdToString(propId), areaId);
+ }
};
struct PropIdAreaIdHash {
@@ -329,12 +340,6 @@
};
// This is for debug purpose only.
-inline std::string propIdToString(int32_t propId) {
- return toString(
- static_cast<aidl::android::hardware::automotive::vehicle::VehicleProperty>(propId));
-}
-
-// This is for debug purpose only.
android::base::Result<int32_t> stringToPropId(const std::string& propName);
// This is for debug purpose only. Converts an area's name to its enum definition.
@@ -362,4 +367,21 @@
} // namespace hardware
} // namespace android
+// Formatter must not be defined inside our namespace.
+template <>
+struct fmt::formatter<android::hardware::automotive::vehicle::PropIdAreaId> {
+ template <typename ParseContext>
+ constexpr auto parse(ParseContext& ctx) {
+ return ctx.begin();
+ }
+
+ template <typename FormatContext>
+ auto format(const android::hardware::automotive::vehicle::PropIdAreaId& p,
+ FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(), "{{propId: {}, areaId: {}}}",
+ android::hardware::automotive::vehicle::propIdToString(p.propId),
+ p.areaId);
+ }
+};
+
#endif // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleUtils_H_
diff --git a/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp
index 1048877..8278376 100644
--- a/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp
@@ -787,6 +787,29 @@
ASSERT_FALSE(result.ok());
}
+TEST(VehicleUtilsTest, testPropIdAreaIdToString) {
+ PropIdAreaId propIdAreaId = {
+ .propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+ .areaId = 0,
+ };
+
+ ASSERT_EQ(propIdAreaId.toString(), "{propId: PERF_VEHICLE_SPEED, areaId: 0}");
+}
+
+TEST(VehicleUtilsTest, testPropIdAreaIdFormatter) {
+ PropIdAreaId propIdAreaId1 = {
+ .propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+ .areaId = 0,
+ };
+ PropIdAreaId propIdAreaId2 = {
+ .propId = toInt(VehicleProperty::HVAC_FAN_SPEED),
+ .areaId = 1,
+ };
+
+ ASSERT_EQ(fmt::format("{}", std::vector<PropIdAreaId>{propIdAreaId1, propIdAreaId2}),
+ "[{propId: PERF_VEHICLE_SPEED, areaId: 0}, {propId: HVAC_FAN_SPEED, areaId: 1}]");
+}
+
class InvalidPropValueTest : public testing::TestWithParam<InvalidPropValueTestCase> {};
INSTANTIATE_TEST_SUITE_P(InvalidPropValueTests, InvalidPropValueTest,
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/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
index 2f16fca..cac1901 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
@@ -95,15 +95,14 @@
bool isContinuousProperty);
// Unsubscribes from the properties for the client.
- // Returns error if the client was not subscribed before, or one of the given property was not
- // subscribed, or one of the property failed to unsubscribe. Caller is safe to retry since
+ // Returns error if one of the property failed to unsubscribe. Caller is safe to retry since
// unsubscribing to an already unsubscribed property is okay (it would be ignored).
// Returns ok if all the requested properties for the client are unsubscribed.
VhalResult<void> unsubscribe(ClientIdType client, const std::vector<int32_t>& propIds);
// Unsubscribes from all the properties for the client.
- // Returns error if the client was not subscribed before or one of the subscribed properties
- // for the client failed to unsubscribe. Caller is safe to retry.
+ // Returns error one of the subscribed properties for the client failed to unsubscribe.
+ // Caller is safe to retry.
// Returns ok if all the properties for the client are unsubscribed.
VhalResult<void> unsubscribe(ClientIdType client);
diff --git a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
index 1e55a1a..509d1c3 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
@@ -49,7 +49,9 @@
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::MinMaxSupportedValueResult;
using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResults;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
@@ -57,6 +59,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 +80,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 +972,171 @@
return ScopedAStatus::ok();
}
+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;
+}
+
+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<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
- SupportedValuesListResults*) {
- // TODO(b/381020465): Add relevant implementation.
- return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ 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<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
- MinMaxSupportedValueResults*) {
- // TODO(b/381020465): Add relevant implementation.
- return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ const std::vector<VhalPropIdAreaId>& vhalPropIdAreaIds,
+ MinMaxSupportedValueResults* minMaxSupportedValueResults) {
+ std::vector<size_t> toHardwareRequestCounters;
+ std::vector<PropIdAreaId> toHardwarePropIdAreaIds;
+ std::vector<MinMaxSupportedValueResult> 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("getMinMaxSupportedValue: %s",
+ hasSupportedValueInfoResult.error().message().c_str());
+ results[requestCounter] = MinMaxSupportedValueResult{.status = StatusCode::INVALID_ARG,
+ .minSupportedValue = std::nullopt,
+ .maxSupportedValue = std::nullopt};
+ continue;
+ }
+
+ const auto& hasSupportedValueInfo = *(hasSupportedValueInfoResult.value());
+ if (hasSupportedValueInfo.hasMinSupportedValue ||
+ hasSupportedValueInfo.hasMaxSupportedValue) {
+ toHardwarePropIdAreaIds.push_back(PropIdAreaId{.propId = propId, .areaId = areaId});
+ toHardwareRequestCounters.push_back(requestCounter);
+ } else {
+ results[requestCounter] = MinMaxSupportedValueResult{.status = StatusCode::OK,
+ .minSupportedValue = std::nullopt,
+ .maxSupportedValue = std::nullopt};
+ continue;
+ }
+ }
+ if (toHardwarePropIdAreaIds.size() != 0) {
+ std::vector<MinMaxSupportedValueResult> resultsFromHardware =
+ mVehicleHardware->getMinMaxSupportedValues(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(
+ "getMinMaxSupportedValue: 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), minMaxSupportedValueResults);
+ if (!status.isOk()) {
+ int statusCode = status.getServiceSpecificError();
+ ALOGE("getMinMaxSupportedValue: failed to marshal result into large parcelable, error: "
+ "%s, code: %d",
+ status.getMessage(), statusCode);
+ return status;
+ }
+ return ScopedAStatus::ok();
}
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/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
index 14ee707..2d09e02 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
@@ -345,8 +345,8 @@
std::scoped_lock<std::mutex> lockGuard(mLock);
if (mSubscribedPropsByClient.find(clientId) == mSubscribedPropsByClient.end()) {
- return StatusError(StatusCode::INVALID_ARG)
- << "No property was subscribed for the callback";
+ ALOGW("No property was subscribed for the callback, unsubscribe does nothing");
+ return {};
}
std::vector<PropIdAreaId> propIdAreaIdsToUnsubscribe;
@@ -378,7 +378,8 @@
std::scoped_lock<std::mutex> lockGuard(mLock);
if (mSubscribedPropsByClient.find(clientId) == mSubscribedPropsByClient.end()) {
- return StatusError(StatusCode::INVALID_ARG) << "No property was subscribed for this client";
+ ALOGW("No property was subscribed for this client, unsubscribe does nothing");
+ return {};
}
auto& subscriptions = mSubscribedPropsByClient[clientId];
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
index ad34a4c..4df5ba3 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,20 @@
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::MinMaxSupportedValueResult;
+using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResults;
+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 +92,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 +121,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) {
@@ -1828,12 +1842,11 @@
ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::ACCESS_DENIED));
}
-TEST_F(DefaultVehicleHalTest, testUnsubscribeFailure) {
+TEST_F(DefaultVehicleHalTest, testUnsubscribeNotSubscribedProperty) {
auto status = getClient()->unsubscribe(getCallbackClient(),
std::vector<int32_t>({GLOBAL_ON_CHANGE_PROP}));
- ASSERT_FALSE(status.isOk()) << "unsubscribe to a not-subscribed property must fail";
- ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
+ ASSERT_TRUE(status.isOk()) << "unsubscribe to a not-subscribed property must do nothing";
}
TEST_F(DefaultVehicleHalTest, testHeartbeatEvent) {
@@ -2121,6 +2134,290 @@
}
}
+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)
+ << "Must return INVALID_ARG for global property without area config";
+ 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);
+}
+
+TEST_F(DefaultVehicleHalTest, testGetMinMaxSupportedValue) {
+ auto testConfigs = std::vector<VehiclePropConfig>(
+ {// This ia valid request, but no supported values are specified.
+ VehiclePropConfig{
+ .prop = testInt32VecProp(1),
+ .areaConfigs =
+ {
+ {.areaId = 0,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasMinSupportedValue = false,
+ .hasMaxSupportedValue = 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{
+ .hasMinSupportedValue = true,
+ .hasMaxSupportedValue = false,
+ }},
+ },
+ }});
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ MockVehicleHardware* hardwarePtr = hardware.get();
+ hardware->setPropertyConfigs(testConfigs);
+
+ MinMaxSupportedValueResult resultFromHardware = {
+ .status = StatusCode::OK,
+ .minSupportedValue = std::optional<RawPropValues>{RawPropValues{.int32Values = {1}}},
+ .maxSupportedValue = std::nullopt,
+ };
+ auto response = std::vector<MinMaxSupportedValueResult>({resultFromHardware});
+ hardware->setMinMaxSupportedValueResponse(response);
+
+ auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ MinMaxSupportedValueResults 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->getMinMaxSupportedValue(
+ std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2, propIdAreaId3,
+ propIdAreaId4},
+ &results);
+
+ ASSERT_TRUE(status.isOk()) << "Get non-okay status from getMinMaxSupportedValue"
+ << status.getMessage();
+ ASSERT_THAT(hardwarePtr->getMinMaxSupportedValueRequest(),
+ ElementsAre(PropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4}))
+ << "Only valid request 4 should get to hardware";
+
+ ASSERT_EQ(results.payloads.size(), 4u);
+ MinMaxSupportedValueResult result = results.payloads[0];
+ ASSERT_EQ(result.status, StatusCode::OK)
+ << "Must return OK even if the min/max supported values are not specified";
+ ASSERT_FALSE(result.minSupportedValue.has_value())
+ << "Must return null min supported value if not specified";
+ ASSERT_FALSE(result.maxSupportedValue.has_value())
+ << "Must return null max supported value 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.minSupportedValue.has_value());
+ ASSERT_FALSE(result.maxSupportedValue.has_value());
+
+ result = results.payloads[2];
+ ASSERT_EQ(result.status, StatusCode::INVALID_ARG)
+ << "Must return INVALID_ARG for global property without area config";
+ ASSERT_FALSE(result.minSupportedValue.has_value());
+ ASSERT_FALSE(result.maxSupportedValue.has_value());
+
+ result = results.payloads[3];
+ ASSERT_EQ(result.status, StatusCode::OK);
+ ASSERT_TRUE(result.minSupportedValue.has_value());
+ ASSERT_EQ(result.minSupportedValue->int32Values.size(), 1u);
+ ASSERT_EQ(result.minSupportedValue->int32Values[0], 1);
+ ASSERT_FALSE(result.maxSupportedValue.has_value());
+}
+
+TEST_F(DefaultVehicleHalTest, testGetMinMaxSupportedValue_propIdAreaIdNotFound) {
+ auto testConfigs = std::vector<VehiclePropConfig>({
+ VehiclePropConfig{
+ .prop = testInt32VecWindowProp(1),
+ .areaConfigs =
+ {
+ {.areaId = 1,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasMinSupportedValue = true,
+ .hasMaxSupportedValue = 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());
+
+ MinMaxSupportedValueResults 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->getMinMaxSupportedValue(
+ std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2}, &results);
+
+ ASSERT_TRUE(status.isOk()) << "Get non-okay status from getMinMaxSupportedValue"
+ << status.getMessage();
+ ASSERT_EQ(results.payloads.size(), 2u);
+ MinMaxSupportedValueResult 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..ae2b5a2 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
@@ -26,10 +26,12 @@
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
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 +202,20 @@
return propIdAreaIds;
}
+std::vector<SupportedValuesListResult> MockVehicleHardware::getSupportedValuesLists(
+ const std::vector<PropIdAreaId>& propIdAreaIds) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSupportedValuesListRequest = propIdAreaIds;
+ return mSupportedValuesListResponse;
+}
+
+std::vector<MinMaxSupportedValueResult> MockVehicleHardware::getMinMaxSupportedValues(
+ const std::vector<PropIdAreaId>& propIdAreaIds) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mMinMaxSupportedValueRequest = propIdAreaIds;
+ return mMinMaxSupportedValueResponse;
+}
+
void MockVehicleHardware::registerOnPropertyChangeEvent(
std::unique_ptr<const PropertyChangeCallback> callback) {
std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -267,6 +283,28 @@
mEventBatchingWindow = window;
}
+void MockVehicleHardware::setSupportedValuesListResponse(
+ const std::vector<SupportedValuesListResult>& response) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSupportedValuesListResponse = response;
+}
+
+void MockVehicleHardware::setMinMaxSupportedValueResponse(
+ const std::vector<MinMaxSupportedValueResult>& response) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mMinMaxSupportedValueResponse = response;
+}
+
+std::vector<PropIdAreaId> MockVehicleHardware::getSupportedValuesListRequest() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mSupportedValuesListRequest;
+}
+
+std::vector<PropIdAreaId> MockVehicleHardware::getMinMaxSupportedValueRequest() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mMinMaxSupportedValueRequest;
+}
+
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..d1e9771 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
@@ -67,6 +67,10 @@
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;
+ std::vector<aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult>
+ getMinMaxSupportedValues(const std::vector<PropIdAreaId>& propIdAreaIds) override;
// Test functions.
void setPropertyConfigs(
@@ -78,6 +82,14 @@
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 setMinMaxSupportedValueResponse(
+ const std::vector<
+ aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult>&
+ response);
void setGetValueResponder(
std::function<aidl::android::hardware::automotive::vehicle::StatusCode(
std::shared_ptr<const GetValuesCallback>,
@@ -88,6 +100,8 @@
nextGetValueRequests();
std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>
nextSetValueRequests();
+ std::vector<PropIdAreaId> getSupportedValuesListRequest();
+ std::vector<PropIdAreaId> getMinMaxSupportedValueRequest();
void setStatus(const char* functionName,
aidl::android::hardware::automotive::vehicle::StatusCode status);
void setSleepTime(int64_t timeInNano);
@@ -118,6 +132,12 @@
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<PropIdAreaId> mMinMaxSupportedValueRequest GUARDED_BY(mLock);
+ mutable std::vector<aidl::android::hardware::automotive::vehicle::SupportedValuesListResult>
+ mSupportedValuesListResponse GUARDED_BY(mLock);
+ mutable std::vector<aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult>
+ mMinMaxSupportedValueResponse 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;
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
index 5d58de5..2ac3a73 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
@@ -351,6 +351,10 @@
std::vector<int32_t>({0, 1, 2}));
ASSERT_TRUE(result.ok()) << "unsubscribe an unsubscribed property must do nothing";
+ result = getManager()->unsubscribe(getCallbackClient()->asBinder().get(),
+ std::vector<int32_t>({0, 1, 2}));
+ ASSERT_TRUE(result.ok()) << "retry an unsubscribe operation must not throw error";
+
std::vector<VehiclePropValue> updatedValues = {
{
.prop = 0,
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index f8cce1a..797be73 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -1234,6 +1234,22 @@
* The minInt32Value indicates the lowest fan speed.
* The maxInt32Value indicates the highest fan speed.
*
+ * If {@code HasSupportedValueInfo} for a specific area ID is not {@code null}:
+ *
+ * {@code HasSupportedValueInfo.hasMinSupportedValue} and
+ * {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for the specific
+ * area ID.
+ *
+ * {@code MinMaxSupportedValueResult.minSupportedValue} indicates the lowest fan speed.
+ *
+ * {@code MinMaxSupportedValueResult.maxSupportedValue} indicates the highest fan speed.
+ *
+ * All integers between minSupportedValue and maxSupportedValue must be supported.
+ *
+ * At boot, minInt32Value is equal to minSupportedValue, maxInt32Value is equal to
+ * maxSupportedValue.
+ *
+ *
* This property is not in any particular unit but in a specified range of relative speeds.
*
* This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
@@ -1242,6 +1258,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @require_min_max_supported_value
* @version 2
*/
HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
diff --git a/bluetooth/OWNERS b/bluetooth/OWNERS
index f401b8c..df250c8 100644
--- a/bluetooth/OWNERS
+++ b/bluetooth/OWNERS
@@ -1,5 +1,5 @@
# Bug component: 27441
+asoulier@google.com
henrichataing@google.com
-mylesgw@google.com
siyuanh@google.com
diff --git a/boot/aidl/default/Android.bp b/boot/aidl/default/Android.bp
index c1d3c57..2fd2dad 100644
--- a/boot/aidl/default/Android.bp
+++ b/boot/aidl/default/Android.bp
@@ -57,7 +57,7 @@
name: "android.hardware.boot-service.default_recovery",
defaults: ["android.hardware.boot-service_common"],
init_rc: ["android.hardware.boot-service.default_recovery.rc"],
- vintf_fragments: ["android.hardware.boot-service.default.xml"],
+ vintf_fragment_modules: ["android.hardware.boot-service.default.xml.recovery"],
recovery: true,
shared_libs: [
@@ -77,11 +77,16 @@
installable: false,
}
-prebuilt_etc {
+vintf_fragment {
+ name: "android.hardware.boot-service.default.xml.recovery",
+ src: "android.hardware.boot-service.default.xml",
+ recovery: true,
+}
+
+vintf_fragment {
name: "android.hardware.boot-service.default.xml",
src: "android.hardware.boot-service.default.xml",
- sub_dir: "vintf",
- installable: false,
+ vendor: true,
}
apex {
@@ -98,6 +103,8 @@
],
prebuilts: [
"android.hardware.boot-service.default.rc",
+ ],
+ vintf_fragment_modules: [
"android.hardware.boot-service.default.xml",
],
}
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 015cae0..f19a4e5 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -790,14 +790,12 @@
ScopedAStatus BroadcastRadio::setParameters(
[[maybe_unused]] const vector<VendorKeyValue>& parameters,
vector<VendorKeyValue>* returnParameters) {
- // TODO(b/243682330) Support vendor parameter functionality
*returnParameters = {};
return ScopedAStatus::ok();
}
ScopedAStatus BroadcastRadio::getParameters([[maybe_unused]] const vector<string>& keys,
vector<VendorKeyValue>* returnParameters) {
- // TODO(b/243682330) Support vendor parameter functionality
*returnParameters = {};
return ScopedAStatus::ok();
}
diff --git a/contexthub/aidl/default/Android.bp b/contexthub/aidl/default/Android.bp
index c0b147c..d4d03e4 100644
--- a/contexthub/aidl/default/Android.bp
+++ b/contexthub/aidl/default/Android.bp
@@ -89,5 +89,6 @@
prebuilts: [
"android.hardware.contexthub-service.example.rc",
"contexthub-default.xml",
+ "android.hardware.context_hub.prebuilt.xml",
],
}
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 80c9575..19d9639 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -70,21 +70,7 @@
} // anonymous namespace
-ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
- ContextHubInfo hub = {};
- hub.name = "Mock Context Hub";
- hub.vendor = "AOSP";
- hub.toolchain = "n/a";
- hub.id = kMockHubId;
- hub.peakMips = 1;
- hub.maxSupportedMessageLengthBytes = 4096;
- hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
- hub.chreApiMajorVersion = 1;
- hub.chreApiMinorVersion = 6;
- hub.supportsReliableMessages = false;
-
- out_contextHubInfos->push_back(hub);
-
+ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* /* out_contextHubInfos */) {
return ScopedAStatus::ok();
}
@@ -197,43 +183,26 @@
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- ContextHubInfo hub = {};
- hub.name = "Mock Context Hub";
- hub.vendor = "AOSP";
- hub.toolchain = "n/a";
- hub.id = kMockHubId;
- hub.peakMips = 1;
- hub.maxSupportedMessageLengthBytes = 4096;
- hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
- hub.chreApiMajorVersion = 1;
- hub.chreApiMinorVersion = 6;
- hub.supportsReliableMessages = false;
-
- HubInfo hubInfo1 = {};
- hubInfo1.hubId = hub.chrePlatformId;
- hubInfo1.hubDetails = HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::contextHubInfo>(hub);
-
VendorHubInfo vendorHub = {};
vendorHub.name = "Mock Vendor Hub";
vendorHub.version = 42;
- HubInfo hubInfo2 = {};
- hubInfo2.hubId = kMockVendorHubId;
- hubInfo2.hubDetails =
+ HubInfo hubInfo1 = {};
+ hubInfo1.hubId = kMockVendorHubId;
+ hubInfo1.hubDetails =
HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
VendorHubInfo vendorHub2 = {};
vendorHub2.name = "Mock Vendor Hub 2";
vendorHub2.version = 24;
- HubInfo hubInfo3 = {};
- hubInfo3.hubId = kMockVendorHub2Id;
- hubInfo3.hubDetails =
+ HubInfo hubInfo2 = {};
+ hubInfo2.hubId = kMockVendorHub2Id;
+ hubInfo2.hubDetails =
HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub2);
_aidl_return->push_back(hubInfo1);
_aidl_return->push_back(hubInfo2);
- _aidl_return->push_back(hubInfo3);
return ScopedAStatus::ok();
};
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index aa611ce..1df1a99 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -62,6 +62,7 @@
// 6612b522-b717-41c8-b48d-c0b1cc64e142
constexpr std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+
const String16 kName{"VtsAidlHalContextHubTargetTest"};
const String16 kEchoServiceName{"android.hardware.contexthub.test.EchoService"};
@@ -72,19 +73,29 @@
contextHub = android::waitForDeclaredService<IContextHub>(
String16(std::get<0>(GetParam()).c_str()));
ASSERT_NE(contextHub, nullptr);
+ }
+
+ uint32_t getHubId() { return std::get<1>(GetParam()); }
+
+ sp<IContextHub> contextHub;
+
+ void testSettingChanged(Setting setting);
+};
+
+class ContextHubAidlWithTestMode : public ContextHubAidl {
+ public:
+ virtual void SetUp() override {
+ ContextHubAidl::SetUp();
// Best effort enable test mode - this may not be supported on older HALS, so we
// ignore the return value.
contextHub->setTestMode(/* enable= */ true);
}
- virtual void TearDown() override { contextHub->setTestMode(/* enable= */ false); }
-
- uint32_t getHubId() { return std::get<1>(GetParam()); }
-
- void testSettingChanged(Setting setting);
-
- sp<IContextHub> contextHub;
+ virtual void TearDown() override {
+ contextHub->setTestMode(/* enable= */ false);
+ ContextHubAidl::TearDown();
+ }
};
TEST_P(ContextHubAidl, TestGetHubs) {
@@ -546,7 +557,7 @@
bool mWasOnEndpointSessionOpenCompleteCalled = false;
};
-TEST_P(ContextHubAidl, RegisterEndpoint) {
+TEST_P(ContextHubAidlWithTestMode, RegisterEndpoint) {
EndpointInfo endpointInfo;
endpointInfo.id.id = 1;
endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
@@ -563,7 +574,7 @@
}
}
-TEST_P(ContextHubAidl, RegisterEndpointSameNameFailure) {
+TEST_P(ContextHubAidlWithTestMode, RegisterEndpointSameNameFailure) {
EndpointInfo endpointInfo;
endpointInfo.id.id = 2;
endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
@@ -589,7 +600,7 @@
EXPECT_FALSE(contextHub->registerEndpoint(endpointInfo2).isOk());
}
-TEST_P(ContextHubAidl, RegisterEndpointSameIdFailure) {
+TEST_P(ContextHubAidlWithTestMode, RegisterEndpointSameIdFailure) {
EndpointInfo endpointInfo;
endpointInfo.id.id = 4;
endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
@@ -615,7 +626,7 @@
EXPECT_FALSE(contextHub->registerEndpoint(endpointInfo2).isOk());
}
-TEST_P(ContextHubAidl, UnregisterEndpoint) {
+TEST_P(ContextHubAidlWithTestMode, UnregisterEndpoint) {
EndpointInfo endpointInfo;
endpointInfo.id.id = 6;
endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
@@ -634,7 +645,7 @@
EXPECT_TRUE(contextHub->unregisterEndpoint(endpointInfo).isOk());
}
-TEST_P(ContextHubAidl, UnregisterEndpointNonexistent) {
+TEST_P(ContextHubAidlWithTestMode, UnregisterEndpointNonexistent) {
EndpointInfo endpointInfo;
endpointInfo.id.id = 100;
endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
@@ -651,7 +662,7 @@
}
}
-TEST_P(ContextHubAidl, RegisterCallback) {
+TEST_P(ContextHubAidlWithTestMode, RegisterEndpointCallback) {
auto cb = sp<TestEndpointCallback>::make();
Status status = contextHub->registerEndpointCallback(cb);
if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
@@ -662,7 +673,7 @@
}
}
-TEST_P(ContextHubAidl, OpenEndpointSessionInvalidRange) {
+TEST_P(ContextHubAidlWithTestMode, OpenEndpointSessionInvalidRange) {
auto cb = sp<TestEndpointCallback>::make();
Status status = contextHub->registerEndpointCallback(cb);
if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
@@ -713,7 +724,7 @@
.isOk());
}
-TEST_P(ContextHubAidl, OpenEndpointSessionAndSendMessageEchoesBack) {
+TEST_P(ContextHubAidlWithTestMode, OpenEndpointSessionAndSendMessageEchoesBack) {
auto cb = sp<TestEndpointCallback>::make();
Status status = contextHub->registerEndpointCallback(cb);
if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
@@ -789,13 +800,17 @@
INSTANTIATE_TEST_SUITE_P(ContextHub, ContextHubAidl, testing::ValuesIn(generateContextHubMapping()),
PrintGeneratedTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextHubAidlWithTestMode);
+INSTANTIATE_TEST_SUITE_P(ContextHub, ContextHubAidlWithTestMode,
+ testing::ValuesIn(generateContextHubMapping()), PrintGeneratedTest);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextHubTransactionTest);
INSTANTIATE_TEST_SUITE_P(ContextHub, ContextHubTransactionTest,
testing::ValuesIn(generateContextHubMapping()), PrintGeneratedTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->setThreadPoolMaxThreadCount(2);
ProcessState::self()->startThreadPool();
return RUN_ALL_TESTS();
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index 2945dab..e6d2fdf 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -45,6 +45,9 @@
void deleteAllKeys();
void destroyAttestationIds();
android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken);
+ /**
+ * @deprecated Method has never been used due to design limitations
+ */
void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
void earlyBootEnded();
byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index b57dd8a..cafec70 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -826,6 +826,7 @@
*
* @param passwordOnly N/A due to the deprecation
* @param timestampToken N/A due to the deprecation
+ * @deprecated Method has never been used due to design limitations
*/
void deviceLocked(in boolean passwordOnly, in @nullable TimeStampToken timestampToken);
@@ -964,10 +965,11 @@
* IKeyMintDevice must ignore KeyParameters with tags not included in the following list:
*
* o Tag::MODULE_HASH: holds a hash that must be included in attestations in the moduleHash
- * field of the software enforced authorization list. If Tag::MODULE_HASH is included in more
- * than one setAdditionalAttestationInfo call, the implementation should compare the initial
- * KeyParamValue with the more recent one. If they differ, the implementation should fail with
- * ErrorCode::MODULE_HASH_ALREADY_SET. If they are the same, no action needs to be taken.
+ * field of the software enforced authorization list.
+ *
+ * @return error ErrorCode::MODULE_HASH_ALREADY_SET if this is not the first time
+ * setAdditionalAttestationInfo is called with Tag::MODULE_HASH, and the associated
+ * KeyParamValue of the current call doesn't match the KeyParamValue of the first call.
*/
void setAdditionalAttestationInfo(in KeyParameter[] info);
}
diff --git a/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl b/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
index b31a06c..99eb761 100644
--- a/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
+++ b/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
@@ -64,7 +64,7 @@
int keySizeBytes;
}
union DerivedKeyPolicy {
- android.hardware.security.see.hwcrypto.IHwCryptoKey.ClearKeyPolicy clearKey;
+ android.hardware.security.see.hwcrypto.IHwCryptoKey.ClearKeyPolicy clearKeyPolicy;
byte[] opaqueKey;
}
parcelable DerivedKeyParameters {
diff --git a/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl b/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
index 7c87dd3..3adb2f9 100644
--- a/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
+++ b/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see.hwcrypto/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
@@ -34,5 +34,5 @@
package android.hardware.security.see.hwcrypto;
@VintfStability
interface IHwCryptoOperations {
- android.hardware.security.see.hwcrypto.CryptoOperationResult[] processCommandList(inout android.hardware.security.see.hwcrypto.CryptoOperationSet[] operations, out android.hardware.security.see.hwcrypto.CryptoOperationErrorAdditionalInfo additionalErrorInfo);
+ android.hardware.security.see.hwcrypto.CryptoOperationResult[] processCommandList(inout android.hardware.security.see.hwcrypto.CryptoOperationSet[] operations);
}
diff --git a/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl b/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
index 97a4c37..93d6cbc 100644
--- a/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
+++ b/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
@@ -107,10 +107,12 @@
* If used we will derive a clear key and pass it back as an array of bytes on
* <code>HwCryptoKeyMaterial::explicitKey</code>.
*/
- ClearKeyPolicy clearKey;
+ ClearKeyPolicy clearKeyPolicy;
/*
* Policy for the newly derived opaque key. Defines how the key can be used and its type.
+ * Its definition can be found in <code>KeyPolicy.cddl</code>, which is basically a CBOR
+ * serialization of the file <code>KeyPolicy.aidl</code>.
*/
byte[] opaqueKey;
}
@@ -154,11 +156,14 @@
* Key to be used to derive the new key using HKDF.
*
* @return:
- * A DiceCurrentBoundKeyResult containint the versioned key tied the current client version
+ * A DiceCurrentBoundKeyResult containing the versioned key tied the current client version
* on success.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - BAD_PARAMETER if an invalid DeviceKeyId is requested.
+ * - INVALID_KEY if an opaque key is provided that is not suitable for key derivation.
*/
DiceCurrentBoundKeyResult deriveCurrentDicePolicyBoundKey(
in DiceBoundDerivationKey derivationKey);
@@ -184,7 +189,11 @@
* success.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - BAD_PARAMETER if an invalid DeviceKeyId is requested or if dicePolicyForKeyVersion
+ * is not a valid encrypted DICE policy.
+ * - INVALID_KEY if an opaque key is provided that is not suitable for key derivation.
*/
DiceBoundKeyResult deriveDicePolicyBoundKey(
in DiceBoundDerivationKey derivationKey, in byte[] dicePolicyForKeyVersion);
@@ -197,10 +206,15 @@
* file for more information.
*
* @return:
- * A HwCryptoKeyMaterial containing the derived key on success.
+ * A <code>DerivedKey</code> containing the derived key on success.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - BAD_PARAMETER if an invalid key policy is provided or if the key policy conflicts
+ * with the requested key.
+ * - SERIALIZATION_ERROR if the provided key policy is not a valid CBOR key policy.
+ * - INVALID_KEY if an opaque key is provided that is not suitable for key derivation.
*/
DerivedKey deriveKey(in DerivedKeyParameters parameters);
@@ -233,7 +247,11 @@
* IOpaqueKey on success.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - BAD_PARAMETER if an invalid Key policy is provided or if the key policy conflicts
+ * with provided key material.
+ * - ALLOCATION_ERROR if the system runs out of memory while carring out the operation.
*/
IOpaqueKey importClearKey(in ExplicitKeyMaterial keyMaterial, in KeyPolicy newKeyPolicy);
@@ -248,7 +266,9 @@
* passing the receiver DICE policy to insure that only that receiver can import the key.
*
* @return:
- * byte[] on success, which is the caller encrypted DICE policy.
+ * byte[] on success, which is the caller encrypted DICE policy. The DICE policy follows
+ * the structure defined on DicePolicy.cddl, located under
+ * hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/
*/
byte[] getCurrentDicePolicy();
@@ -266,10 +286,14 @@
* DICE policy used to seal the exported key.
*
* @return:
- * An IOpaqueKey that can be directly be used on the local HWCrypto service on success.
+ * An IOpaqueKey that can be directly used on the local HWCrypto service on success.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - BAD_PARAMETER if an invalid encrypted sealing DICE policy is provided.
+ * - ALLOCATION_ERROR if the system runs out of memory while carring out the operation.
+ * - UNAUTHORIZED if the sealingDicePolicy do not match the caller.
*/
IOpaqueKey keyTokenImport(in OpaqueKeyToken requestedKey, in byte[] sealingDicePolicy);
@@ -287,8 +311,9 @@
* An IOpaqueKey corresponding to the requested key slot on success.
*
* @throws:
- * ServiceSpecificException <code>UNAUTHORIZED</code> if the caller cannot access the
- * requested key, another specific error based on <code>HalErrorCode</code> otherwise.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - UNAUTHORIZED if the caller cannot access the requested key.
*/
IOpaqueKey getKeyslotData(KeySlot slotId);
}
diff --git a/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl b/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
index 9df6d67..dbe4d80 100644
--- a/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
+++ b/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
@@ -31,19 +31,21 @@
*
* @param operations:
* Parameter containing 1 or more set of commands to execute. Additionally, each set can
- * also contain a context on which the commands will be executed.
- *
- * @param additionalErrorInfo:
- * Structure containing additional info when errors are encountered. Only valid if the
- * function failed its execution.
+ * also contain a context on which the commands will be executed. The parameter has type
+ * inout because it can contain buffers used to write the output of the operation.
*
* @return:
* CryptoOperationResult[] on success, which can contain a context to continue executing
* each of the provided operations sets.
*
* @throws:
- * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs.
+ * ServiceSpecificException based on <code>HalErrorCode</code> if any error occurs,
+ * in particular:
+ * - INVALID_KEY if the provided key is not compatible with the operation requested.
+ * - BAD_STATE if the provided <code>CryptoOperationSet</code> contains operations that
+ * cannot be carried out in the current server state.
+ * - UNSUPPORTED if the requested operation is not supported by the server.
+ * - ALLOCATION_ERROR if the system runs out of memory while carring out the operation.
*/
- CryptoOperationResult[] processCommandList(inout CryptoOperationSet[] operations,
- out CryptoOperationErrorAdditionalInfo additionalErrorInfo);
+ CryptoOperationResult[] processCommandList(inout CryptoOperationSet[] operations);
}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
index c68d8fd..202082e 100644
--- a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
@@ -276,3 +276,28 @@
}
return std::optional<std::vector<std::optional<OuiKeyedData>>>{dataList};
}
+
+IWifiChip::ApIfaceParams generateApIfaceParams(IfaceConcurrencyType type, bool uses_mlo,
+ int oui_size) {
+ IWifiChip::ApIfaceParams params;
+ params.ifaceType = type;
+ params.usesMlo = uses_mlo;
+ params.vendorData = generateOuiKeyedDataListOptional(oui_size);
+ return params;
+}
+
+std::shared_ptr<IWifiApIface> getWifiApOrBridgedApIface(std::shared_ptr<IWifiChip> wifi_chip,
+ IWifiChip::ApIfaceParams params) {
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ std::shared_ptr<IWifiApIface> iface;
+ if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
+ return nullptr;
+ }
+ auto status = wifi_chip->createApOrBridgedApIfaceWithParams(params, &iface);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ return iface;
+}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
index 9b47a9f..6d98bf0 100644
--- a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
@@ -43,6 +43,8 @@
std::shared_ptr<IWifiApIface> getWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name);
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
+std::shared_ptr<IWifiApIface> getWifiApOrBridgedApIface(std::shared_ptr<IWifiChip> wifi_chip,
+ IWifiChip::ApIfaceParams params);
// Configure the chip in a mode to support the creation of the provided iface type.
bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
IfaceConcurrencyType type, int* configured_mode_id);
@@ -57,3 +59,7 @@
// Generate test vendor data.
std::vector<OuiKeyedData> generateOuiKeyedDataList(int size);
std::optional<std::vector<std::optional<OuiKeyedData>>> generateOuiKeyedDataListOptional(int size);
+
+// Generate test ApIfaceParams
+IWifiChip::ApIfaceParams generateApIfaceParams(IfaceConcurrencyType type, bool uses_mlo,
+ int oui_size);
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
index a1b9ce1..b4cb030 100644
--- a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -52,6 +52,7 @@
stopWifiService(getInstanceName());
wifi_chip_ = getWifiChip(getInstanceName());
ASSERT_NE(nullptr, wifi_chip_.get());
+ ASSERT_TRUE(wifi_chip_->getInterfaceVersion(&interface_version_).isOk());
}
void TearDown() override { stopWifiService(getInstanceName()); }
@@ -139,6 +140,7 @@
const char* getInstanceName() { return GetParam().c_str(); }
std::shared_ptr<IWifiChip> wifi_chip_;
+ int interface_version_;
};
class WifiChipEventCallback : public BnWifiChipEventCallback {
@@ -902,6 +904,89 @@
}
}
+/**
+ * CreateApOrBridgedApIfaceWithParams for signal ap.
+ */
+TEST_P(WifiChipAidlTest, CreateApOrBridgedApIfaceWithParams_signal_ap) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "CreateApOrBridgedApIfaceWithParams is available as of WifiChip V3";
+ }
+ if (!isConcurrencyTypeSupported(IfaceConcurrencyType::AP)) {
+ GTEST_SKIP() << "AP is not supported";
+ }
+
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip.get());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApOrBridgedApIface(
+ wifi_chip, generateApIfaceParams(IfaceConcurrencyType::AP, false, 0));
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+}
+
+/**
+ * CreateApOrBridgedApIfaceWithParams for non mlo bridged ap.
+ */
+TEST_P(WifiChipAidlTest, CreateApOrBridgedApIfaceWithParams_non_mlo_bridged_ap) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "CreateApOrBridgedApIfaceWithParams is available as of WifiChip V3";
+ }
+ bool isBridgedSupport = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
+ if (!isBridgedSupport) {
+ GTEST_SKIP() << "Missing Bridged AP support";
+ }
+
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip.get());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApOrBridgedApIface(
+ wifi_chip, generateApIfaceParams(IfaceConcurrencyType::AP_BRIDGED, false, 0));
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::string br_name;
+ std::vector<std::string> instances;
+ bool uses_mlo;
+ EXPECT_TRUE(wifi_ap_iface->getName(&br_name).isOk());
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+ EXPECT_TRUE(wifi_ap_iface->usesMlo(&uses_mlo).isOk());
+ EXPECT_FALSE(uses_mlo);
+ EXPECT_EQ(instances.size(), 2);
+}
+
+/**
+ * CreateApOrBridgedApIfaceWithParams for mlo bridged ap.
+ */
+TEST_P(WifiChipAidlTest, CreateApOrBridgedApIfaceWithParams_mlo_bridged_ap) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "CreateApOrBridgedApIfaceWithParams is available as of WifiChip V3";
+ }
+ bool isBridgedSupport = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
+ if (!isBridgedSupport) {
+ GTEST_SKIP() << "Missing Bridged AP support";
+ }
+
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ if (!(features & static_cast<int32_t>(IWifiChip::FeatureSetMask::MLO_SAP))) {
+ GTEST_SKIP() << "MLO_SAP is not supported by vendor.";
+ }
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip.get());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApOrBridgedApIface(
+ wifi_chip, generateApIfaceParams(IfaceConcurrencyType::AP_BRIDGED, true, 0));
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::string br_name;
+ std::vector<std::string> instances;
+ bool uses_mlo;
+ EXPECT_TRUE(wifi_ap_iface->getName(&br_name).isOk());
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+ EXPECT_TRUE(wifi_ap_iface->usesMlo(&uses_mlo).isOk());
+ EXPECT_TRUE(uses_mlo);
+ EXPECT_EQ(instances.size(), 2);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 384ac9a..b0141df 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -84,8 +84,8 @@
oneway void onPmkSaCacheAdded(in android.hardware.wifi.supplicant.PmkSaCacheData pmkSaData);
oneway void onUsdPublishStarted(in int cmdId, in int publishId);
oneway void onUsdSubscribeStarted(in int cmdId, in int subscribeId);
- oneway void onUsdPublishConfigFailed(in int cmdId);
- oneway void onUsdSubscribeConfigFailed(in int cmdId);
+ oneway void onUsdPublishConfigFailed(in int cmdId, in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.UsdConfigErrorCode errorCode);
+ oneway void onUsdSubscribeConfigFailed(in int cmdId, in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.UsdConfigErrorCode errorCode);
oneway void onUsdPublishTerminated(in int publishId, in android.hardware.wifi.supplicant.UsdTerminateReasonCode reasonCode);
oneway void onUsdSubscribeTerminated(in int subscribeId, in android.hardware.wifi.supplicant.UsdTerminateReasonCode reasonCode);
oneway void onUsdPublishReplied(in android.hardware.wifi.supplicant.UsdServiceDiscoveryInfo info);
@@ -97,4 +97,10 @@
MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
MULTI_LINK_DYNAMIC_RECONFIG = 2,
}
+ @Backing(type="int") @VintfStability
+ enum UsdConfigErrorCode {
+ FAILURE_UNKNOWN = 0,
+ FAILURE_TIMEOUT = 1,
+ FAILURE_NOT_AVAILABLE = 2,
+ }
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 1ee873a..efbd066 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -439,12 +439,32 @@
void onUsdSubscribeStarted(in int cmdId, in int subscribeId);
/**
+ * Error codes returned by |onUsdPublishConfigFailed| and |onUsdSubscribeConfigFailed|.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum UsdConfigErrorCode {
+ /**
+ * Unknown failure.
+ */
+ FAILURE_UNKNOWN = 0,
+ /**
+ * The requested operation timed out.
+ */
+ FAILURE_TIMEOUT = 1,
+ /**
+ * The requested operation is currently not available.
+ */
+ FAILURE_NOT_AVAILABLE = 2,
+ }
+
+ /**
* Called in response to |ISupplicantStaIface.startUsdPublish| to indicate that the
* publish session could not be configured.
*
* @param cmdId Identifier for the original request.
*/
- void onUsdPublishConfigFailed(in int cmdId);
+ void onUsdPublishConfigFailed(in int cmdId, in UsdConfigErrorCode errorCode);
/**
* Called in response to |ISupplicantStaIface.startUsdSubscribe| to indicate that the
@@ -452,7 +472,7 @@
*
* @param cmdId Identifier for the original request.
*/
- void onUsdSubscribeConfigFailed(in int cmdId);
+ void onUsdSubscribeConfigFailed(in int cmdId, in UsdConfigErrorCode errorCode);
/**
* Called in response to |ISupplicantStaIface.cancelUsdPublish| to indicate that the session
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index da12a82..18b8ccb 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -254,10 +254,12 @@
int32_t /* subscribeId */) override {
return ndk::ScopedAStatus::ok();
}
- ::ndk::ScopedAStatus onUsdPublishConfigFailed(int32_t /* cmdId */) override {
+ ::ndk::ScopedAStatus onUsdPublishConfigFailed(int32_t /* cmdId */,
+ UsdConfigErrorCode /* errorCode */) override {
return ndk::ScopedAStatus::ok();
}
- ::ndk::ScopedAStatus onUsdSubscribeConfigFailed(int32_t /* cmdId */) override {
+ ::ndk::ScopedAStatus onUsdSubscribeConfigFailed(int32_t /* cmdId */,
+ UsdConfigErrorCode /* errorCode */) override {
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus onUsdPublishTerminated(int32_t /* publishId */,