Merge "Add the information if the assistance is not available." into main
diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp
index cea085c..095bb86 100644
--- a/audio/effect/all-versions/default/Android.bp
+++ b/audio/effect/all-versions/default/Android.bp
@@ -52,6 +52,12 @@
"libmedia_headers",
"libmediautils_headers",
],
+
+ cflags: [
+ "-Wall",
+ "-Wthread-safety",
+ "-Werror",
+ ],
}
cc_library_shared {
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 4a9e144..9896653 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -321,8 +321,8 @@
status_t status = mProcessThread->join();
ALOGE_IF(status, "processing thread exit error: %s", strerror(-status));
}
- if (mEfGroup) {
- status_t status = EventFlag::deleteEventFlag(&mEfGroup);
+ if (EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire)) {
+ status_t status = EventFlag::deleteEventFlag(&evFlag);
ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status));
}
mInBuffer.clear();
@@ -437,6 +437,7 @@
Result Effect::analyzeStatus(const char* funcName, const char* subFuncName,
const char* contextDescription, status_t status) {
if (status != OK) {
+ std::lock_guard<std::mutex> lock(mLock);
ALOGW("Effect %p %s %s %s: %s", mHandle, funcName, subFuncName, contextDescription,
strerror(-status));
}
@@ -470,11 +471,14 @@
Return<void> Effect::getConfigImpl(int commandCode, const char* commandName,
GetConfigCallback _hidl_cb) {
- RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig());
uint32_t halResultSize = sizeof(effect_config_t);
effect_config_t halConfig{};
- status_t status =
- (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
+ status_t status = OK;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig());
+ status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
+ }
EffectConfig config;
if (status == OK) {
status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config);
@@ -542,7 +546,10 @@
}
Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) {
- RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+ }
status_t status;
// Create message queue.
if (mStatusMQ) {
@@ -556,16 +563,21 @@
_hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor());
return Void();
}
- status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup);
- if (status != OK || !mEfGroup) {
+ EventFlag* evFlag = nullptr;
+ status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &evFlag);
+ if (status != OK || !evFlag) {
ALOGE("failed creating event flag for status MQ: %s", strerror(-status));
_hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor());
return Void();
}
+ mEfGroup.store(evFlag, std::memory_order_release);
- // Create and launch the thread.
- mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr,
- &mHalOutBufferPtr, tempStatusMQ.get(), mEfGroup, this);
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ // Create and launch the thread.
+ mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr,
+ &mHalOutBufferPtr, tempStatusMQ.get(), evFlag, this);
+ }
status = mProcessThread->run("effect", PRIORITY_URGENT_AUDIO);
if (status != OK) {
ALOGW("failed to start effect processing thread: %s", strerror(-status));
@@ -575,11 +587,15 @@
// For a spatializer effect, we perform scheduler adjustments to reduce glitches and power.
// We do it here instead of the ProcessThread::threadLoop to ensure that mHandle is valid.
- if (effect_descriptor_t halDescriptor{};
- (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR &&
- memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
- const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid());
- ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+ if (effect_descriptor_t halDescriptor{};
+ (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR &&
+ memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
+ const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid());
+ ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+ }
}
mStatusMQ = std::move(tempStatusMQ);
@@ -589,7 +605,10 @@
Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer,
const AudioBuffer& outBuffer) {
- RETURN_IF_EFFECT_CLOSED();
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_IF_EFFECT_CLOSED();
+ }
AudioBufferManager& manager = AudioBufferManager::getInstance();
sp<AudioBufferWrapper> tempInBuffer, tempOutBuffer;
if (!manager.wrap(inBuffer, &tempInBuffer)) {
@@ -614,8 +633,12 @@
}
Result Effect::sendCommand(int commandCode, const char* commandName, uint32_t size, void* data) {
- RETURN_IF_EFFECT_CLOSED();
- status_t status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL);
+ status_t status = OK;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_IF_EFFECT_CLOSED();
+ status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL);
+ }
return analyzeCommandStatus(commandName, sContextCallToCommand, status);
}
@@ -626,9 +649,13 @@
Result Effect::sendCommandReturningData(int commandCode, const char* commandName, uint32_t size,
void* data, uint32_t* replySize, void* replyData) {
- RETURN_IF_EFFECT_CLOSED();
uint32_t expectedReplySize = *replySize;
- status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+ status_t status = OK;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_IF_EFFECT_CLOSED();
+ status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+ }
if (status == OK && *replySize != expectedReplySize) {
status = -ENODATA;
}
@@ -651,8 +678,12 @@
uint32_t size, void* data, uint32_t* replySize,
void* replyData, uint32_t minReplySize,
CommandSuccessCallback onSuccess) {
- RETURN_IF_EFFECT_CLOSED();
- status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+ status_t status = OK;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_IF_EFFECT_CLOSED();
+ status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+ }
Result retval;
if (status == OK && minReplySize >= sizeof(uint32_t) && *replySize >= minReplySize) {
uint32_t commandStatus = *reinterpret_cast<uint32_t*>(replyData);
@@ -860,10 +891,14 @@
}
Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) {
- RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor());
effect_descriptor_t halDescriptor;
memset(&halDescriptor, 0, sizeof(effect_descriptor_t));
- status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor);
+ status_t status = OK;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor());
+ status = (*mHandle)->get_descriptor(mHandle, &halDescriptor);
+ }
EffectDescriptor descriptor;
if (status == OK) {
status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor);
@@ -874,10 +909,6 @@
Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data,
uint32_t resultMaxSize, command_cb _hidl_cb) {
- if (mHandle == kInvalidEffectHandle) {
- _hidl_cb(-ENODATA, hidl_vec<uint8_t>());
- return Void();
- }
uint32_t halDataSize;
std::unique_ptr<uint8_t[]> halData = hidlVecToHal(data, &halDataSize);
uint32_t halResultSize = resultMaxSize;
@@ -897,8 +928,15 @@
}
[[fallthrough]]; // allow 'gtid' overload (checked halDataSize and resultMaxSize).
default:
- status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize,
- resultPtr);
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mHandle == kInvalidEffectHandle) {
+ _hidl_cb(-ENODATA, hidl_vec<uint8_t>());
+ return Void();
+ }
+ status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr,
+ &halResultSize, resultPtr);
+ }
break;
}
hidl_vec<uint8_t> result;
@@ -967,11 +1005,17 @@
return {Result::INVALID_STATE, kInvalidEffectHandle};
}
mStopProcessThread.store(true, std::memory_order_release);
- if (mEfGroup) {
- mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT));
+ EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire);
+ if (evFlag) {
+ evFlag->wake(static_cast<uint32_t>(
+ MessageQueueFlagBits::REQUEST_QUIT));
}
- effect_handle_t handle = mHandle;
- mHandle = kInvalidEffectHandle;
+ effect_handle_t handle;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ handle = mHandle;
+ mHandle = kInvalidEffectHandle;
+ }
#if MAJOR_VERSION <= 5
return {Result::OK, handle};
#elif MAJOR_VERSION >= 6
@@ -984,7 +1028,10 @@
}
Return<Result> Effect::close() {
- RETURN_IF_EFFECT_CLOSED();
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ RETURN_IF_EFFECT_CLOSED();
+ }
auto [result, _] = closeImpl();
return result;
}
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 2bcecec..cc76784 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -25,6 +25,7 @@
#include <memory>
#include <tuple>
#include <vector>
+#include <mutex>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
@@ -194,13 +195,14 @@
static const char* sContextCallFunction;
const bool mIsInput;
- effect_handle_t mHandle;
+ std::mutex mLock;
+ effect_handle_t mHandle GUARDED_BY(mLock);
sp<AudioBufferWrapper> mInBuffer;
sp<AudioBufferWrapper> mOutBuffer;
std::atomic<audio_buffer_t*> mHalInBufferPtr;
std::atomic<audio_buffer_t*> mHalOutBufferPtr;
std::unique_ptr<StatusMQ> mStatusMQ;
- EventFlag* mEfGroup;
+ std::atomic<EventFlag*> mEfGroup;
std::atomic<bool> mStopProcessThread;
sp<Thread> mProcessThread;
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 53e5e99..92681de 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
@@ -1339,7 +1339,7 @@
{
"name": "EV_CHARGE_CURRENT_DRAW_LIMIT",
"value": 291508031,
- "description": "Indicates the maximum current draw threshold for charging set by the user\nconfigArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at boot time.\nIf {@code HasSupportedValueInfo} for the global area ID (0) is not {@code null}, {@code HasSupportedValueInfo#hasMaxSupportedValue} and {@code HasSupportedValueInfo#hasMinSupportedValue} must be {@code true}. {@code MinMaxSupportedValueResult#maxSupportedValue} specifies the max current draw allowed by the vehicle in Amperes at the current moment. {@code MinMaxSupportedValueResult#minSupportedValue} must be 0. At boot, configArray[0] is equal to maxSupportedValue.\nIf the max current draw allowed by the vehicle may change dynamically, {@code HasSupportedValueInfo#hasMaxSupportedValue} must be {@code true} and {@code MinMaxSupportedValueResult#maxSupportedValue} must be implemented.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+ "description": "The vehicle's selected alternating current (AC) EV charging draw limit in Amperes.\nconfigArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at boot time.\nIf {@code HasSupportedValueInfo} for the global area ID (0) is not {@code null}, {@code HasSupportedValueInfo#hasMaxSupportedValue} and {@code HasSupportedValueInfo#hasMinSupportedValue} must be {@code true}. {@code MinMaxSupportedValueResult#maxSupportedValue} specifies the max current draw allowed by the vehicle in Amperes at the current moment. {@code MinMaxSupportedValueResult#minSupportedValue} must be 0. At boot, configArray[0] is equal to maxSupportedValue.\nIf the max current draw allowed by the vehicle may change dynamically, {@code HasSupportedValueInfo#hasMaxSupportedValue} must be {@code true} and {@code MinMaxSupportedValueResult#maxSupportedValue} must be implemented.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
},
{
"name": "EV_CHARGE_PERCENT_LIMIT",
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 a7ecb36..2f1b277 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -6156,7 +6156,7 @@
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
/**
- * Indicates the maximum current draw threshold for charging set by the user
+ * The vehicle's selected alternating current (AC) EV charging draw limit in Amperes.
*
* configArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at
* boot time.
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index d4b0528..7f5e06d 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -96,6 +96,10 @@
static constexpr char ANNOTATION_SUPPORTED_VALUES_IN_CONFIG[] = "legacy_supported_values_in_config";
static constexpr char ANNOTATIONS_DATA_ENUM[] = "data_enum";
+inline VehiclePropertyType getPropertyType(int32_t propId) {
+ return static_cast<VehiclePropertyType>(propId & toInt(VehiclePropertyType::MASK));
+}
+
struct ServiceDescriptor {
std::string name;
bool isAidlService;
@@ -181,10 +185,12 @@
void testGetMinMaxSupportedValueForPropIdAreaId(int32_t propId,
const IHalAreaConfig& areaConfig,
bool minMaxValueRequired);
+ void testGetSupportedValuesListsForPropIdAreaId(int32_t propId,
+ const IHalAreaConfig& areaConfig,
+ bool supportedValuesRequired);
static bool isBooleanGlobalProp(int32_t property) {
- return (property & toInt(VehiclePropertyType::MASK)) ==
- toInt(VehiclePropertyType::BOOLEAN) &&
+ return getPropertyType(property) == VehiclePropertyType::BOOLEAN &&
(property & toInt(VehicleArea::MASK)) == toInt(VehicleArea::GLOBAL);
}
@@ -810,39 +816,36 @@
}
}
-void verifyRawPropValues(const RawPropValues& rawPropValues, int32_t propertyType) {
+void verifyRawPropValues(const RawPropValues& rawPropValues, VehiclePropertyType propertyType) {
switch (propertyType) {
- case toInt(VehiclePropertyType::INT32):
+ case VehiclePropertyType::INT32:
ASSERT_THAT(rawPropValues.int32Values, ::testing::SizeIs(1))
<< "int32Values field must contain exactly one element for INT32 type";
break;
- case toInt(VehiclePropertyType::FLOAT):
+ case VehiclePropertyType::FLOAT:
ASSERT_THAT(rawPropValues.floatValues, ::testing::SizeIs(1))
<< "floatValues field must contain exactly one element for FLOAT type";
break;
- case toInt(VehiclePropertyType::INT64):
+ case VehiclePropertyType::INT64:
ASSERT_THAT(rawPropValues.int64Values, ::testing::SizeIs(1))
<< "int64Values field must contain exactly one element for INT64 type";
break;
default:
- // This must not happen since we already checked this condition in
- // verifyPropertyConfigMinMaxValue
- FAIL() << "minSupportedValue or maxSupportedValue must only be specified for "
- "INT32, INT64 or FLOAT type property";
+ // We do not check for other types.
break;
}
}
void VtsHalAutomotiveTest::testGetMinMaxSupportedValueForPropIdAreaId(
int32_t propId, const IHalAreaConfig& areaConfig, bool minMaxValueRequired) {
- int areaId = areaConfig.getAreaId();
- int propertyType = propId & toInt(VehiclePropertyType::MASK);
+ int32_t areaId = areaConfig.getAreaId();
+ VehiclePropertyType propertyType = getPropertyType(propId);
std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
areaConfig.getHasSupportedValueInfo();
if (!maybeHasSupportedValueInfo.has_value()) {
return;
}
- if (!maybeHasSupportedValueInfo->hasMaxSupportedValue &&
+ if (!maybeHasSupportedValueInfo->hasMinSupportedValue &&
!maybeHasSupportedValueInfo->hasMaxSupportedValue) {
return;
}
@@ -859,8 +862,7 @@
const MinMaxSupportedValueResult& individualResult = (*result)[0];
if (minMaxValueRequired) {
ASSERT_EQ(individualResult.status, StatusCode::OK)
- << "getMinMaxSupportedValue must return okay status if min/max value is required "
- "for";
+ << "getMinMaxSupportedValue must return okay status if min/max value is required";
}
if (individualResult.status != StatusCode::OK) {
return;
@@ -895,19 +897,19 @@
int64_t minInt64Value;
int64_t maxInt64Value;
switch (propertyType) {
- case toInt(VehiclePropertyType::INT32):
+ case VehiclePropertyType::INT32:
minInt32Value = (individualResult.minSupportedValue)->int32Values[0];
maxInt32Value = (individualResult.maxSupportedValue)->int32Values[0];
ASSERT_LE(minInt32Value, maxInt32Value)
<< "minSupportedValue must be less or equal to maxSupportedValue";
break;
- case toInt(VehiclePropertyType::FLOAT):
+ case VehiclePropertyType::FLOAT:
minFloatValue = (individualResult.minSupportedValue)->floatValues[0];
maxFloatValue = (individualResult.maxSupportedValue)->floatValues[0];
ASSERT_LE(minFloatValue, maxFloatValue)
<< "minSupportedValue must be less or equal to maxSupportedValue";
break;
- case toInt(VehiclePropertyType::INT64):
+ case VehiclePropertyType::INT64:
minInt64Value = (individualResult.minSupportedValue)->int64Values[0];
maxInt64Value = (individualResult.maxSupportedValue)->int64Values[0];
ASSERT_LE(minInt64Value, maxInt64Value)
@@ -923,12 +925,12 @@
}
}
-// Test the getMinMaxSupportedValues API. We use this one test case to cover all properties that
+// Test the getMinMaxSupportedValue API. We use this one test case to cover all properties that
// may support this API.
TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetMinMaxSupportedValue) {
if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
- GTEST_SKIP() << "Skip checking testGetMinMaxSupportedValues the behavior is not supported "
- "for current VHAL version";
+ GTEST_SKIP() << "Skip checking getMinMaxSupportedValue because the behavior is not "
+ "supported for current VHAL version";
}
auto configsResult = mVhalClient->getAllPropConfigs();
@@ -956,12 +958,93 @@
}
}
-void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config, int32_t propertyType) {
+void VtsHalAutomotiveTest::testGetSupportedValuesListsForPropIdAreaId(
+ int32_t propId, const IHalAreaConfig& areaConfig, bool supportedValuesRequired) {
+ int32_t areaId = areaConfig.getAreaId();
+ VehiclePropertyType propertyType = getPropertyType(propId);
+ std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
+ areaConfig.getHasSupportedValueInfo();
+ if (!maybeHasSupportedValueInfo.has_value()) {
+ return;
+ }
+ if (!maybeHasSupportedValueInfo->hasSupportedValuesList) {
+ return;
+ }
+ VhalClientResult<std::vector<SupportedValuesListResult>> result =
+ mVhalClient->getSupportedValuesLists({PropIdAreaId{
+ .propId = propId,
+ .areaId = areaId,
+ }});
+ ASSERT_RESULT_OK(result)
+ << "getSupportedValuesLists must return okay result if hasSupportedValuesList is true";
+ ASSERT_THAT(*result, ::testing::SizeIs(1))
+ << "getSupportedValuesLists result list size must be 1 for 1 request";
+ const SupportedValuesListResult& individualResult = (*result)[0];
+ if (supportedValuesRequired) {
+ ASSERT_EQ(individualResult.status, StatusCode::OK)
+ << "getSupportedValuesLists must return okay status if supported values are "
+ "required";
+ }
+ if (individualResult.status != StatusCode::OK) {
+ return;
+ }
+ ASSERT_TRUE(individualResult.supportedValuesList.has_value())
+ << "supportedValuesList field must not be null if hasSupportedValuesList is true";
+ const std::vector<std::optional<RawPropValues>>& supportedValuesList =
+ individualResult.supportedValuesList.value();
+ if (supportedValuesRequired) {
+ ASSERT_THAT(supportedValuesList, ::testing::Not(::testing::IsEmpty()))
+ << "supportedValuesList must not be empty if supported values are required";
+ }
+ for (const std::optional<RawPropValues>& supportedValue : supportedValuesList) {
+ ASSERT_TRUE(supportedValue.has_value())
+ << "Each item in supportedValuesList must not be null";
+ ASSERT_NO_FATAL_FAILURE(verifyRawPropValues(*supportedValue, propertyType))
+ << "one of supported value is not a valid RawPropValues for "
+ << "the property type, value: " << supportedValue->toString();
+ }
+}
+
+// Test the getSupportedValues API. We use this one test case to cover all properties that
+// may support this API.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetSupportedValuesLists) {
+ if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
+ GTEST_SKIP() << "Skip checking getSupportedValuesLists because the behavior is not "
+ "supported for current VHAL version";
+ }
+
+ auto configsResult = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(configsResult.ok())
+ << "Failed to get all property configs, error: " << configsResult.error().message();
+
+ for (const auto& cfgPtr : configsResult.value()) {
+ int32_t propId = cfgPtr->getPropId();
+ bool supportedValuesRequired = false;
+ std::unordered_set<std::string> annotations;
+ auto it = AnnotationsForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+ if (it != AnnotationsForVehicleProperty.end()) {
+ annotations = it->second;
+ }
+ if (annotations.find(ANNOTATION_REQUIRE_SUPPORTED_VALUES) != annotations.end()) {
+ supportedValuesRequired = true;
+ }
+ const std::vector<std::unique_ptr<IHalAreaConfig>>& areaConfigs = cfgPtr->getAreaConfigs();
+ for (const auto& areaCfgPtr : areaConfigs) {
+ EXPECT_NO_FATAL_FAILURE(testGetSupportedValuesListsForPropIdAreaId(
+ propId, *areaCfgPtr, supportedValuesRequired))
+ << "test getSupportedValues failed for property: " << propIdToString(propId)
+ << ", areaId: " << areaCfgPtr->getAreaId();
+ }
+ }
+}
+
+void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config,
+ VehiclePropertyType propertyType) {
for (const auto& areaConfig : config->getAreaConfigs()) {
std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
areaConfig->getHasSupportedValueInfo();
if (areaConfig->getMinInt32Value() != 0 || areaConfig->getMaxInt32Value() != 0) {
- EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT32))
+ EXPECT_EQ(propertyType, VehiclePropertyType::INT32)
<< "minInt32Value and maxInt32Value must not be specified for INT32 type "
"property";
EXPECT_THAT(areaConfig->getMinInt32Value(),
@@ -977,7 +1060,7 @@
}
}
if (areaConfig->getMinFloatValue() != 0 || areaConfig->getMaxFloatValue() != 0) {
- EXPECT_EQ(propertyType, toInt(VehiclePropertyType::FLOAT))
+ EXPECT_EQ(propertyType, VehiclePropertyType::FLOAT)
<< "minFloatValue and maxFloatValue must not be specified for FLOAT type "
"property";
EXPECT_THAT(areaConfig->getMinFloatValue(),
@@ -993,7 +1076,7 @@
}
}
if (areaConfig->getMinInt64Value() != 0 || areaConfig->getMaxInt64Value() != 0) {
- EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT64))
+ EXPECT_EQ(propertyType, VehiclePropertyType::INT64)
<< "minInt64Value and maxInt64Value must not be specified for INT64 type "
"property";
EXPECT_THAT(areaConfig->getMinInt64Value(),
@@ -1011,9 +1094,9 @@
if (maybeHasSupportedValueInfo.has_value() &&
(maybeHasSupportedValueInfo->hasMinSupportedValue ||
maybeHasSupportedValueInfo->hasMaxSupportedValue)) {
- EXPECT_THAT(propertyType, ::testing::AnyOf(toInt(VehiclePropertyType::INT32),
- toInt(VehiclePropertyType::INT64),
- toInt(VehiclePropertyType::FLOAT)))
+ EXPECT_THAT(propertyType,
+ ::testing::AnyOf(VehiclePropertyType::INT32, VehiclePropertyType::INT64,
+ VehiclePropertyType::FLOAT))
<< "HasSupportedValueInfo.hasMinSupportedValue and "
"HasSupportedValueInfo.hasMaxSupportedValue is only allowed to be set to "
"true "
@@ -1022,27 +1105,31 @@
}
}
-void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config, int propertyType) {
+void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config,
+ VehiclePropertyType propertyType) {
for (const auto& areaConfig : config->getAreaConfigs()) {
switch (propertyType) {
- case toInt(VehiclePropertyType::INT32):
+ case VehiclePropertyType::INT32:
EXPECT_FALSE(areaConfig->getMinInt32Value() == 0 &&
areaConfig->getMaxInt32Value() == 0)
<< "minInt32Value and maxInt32Value must not both be 0 because "
"min and max value is required for this property";
break;
- case toInt(VehiclePropertyType::FLOAT):
+ case VehiclePropertyType::FLOAT:
EXPECT_FALSE(areaConfig->getMinFloatValue() == 0 &&
areaConfig->getMaxFloatValue() == 0)
<< "minFloatValue and maxFloatValue must not both be 0 because "
"min and max value is required for this property";
break;
- case toInt(VehiclePropertyType::INT64):
+ case VehiclePropertyType::INT64:
EXPECT_FALSE(areaConfig->getMinInt64Value() == 0 &&
areaConfig->getMaxInt64Value() == 0)
<< "minInt64Value and maxInt64Value must not both be 0 because "
"min and max value is required for this property";
break;
+ default:
+ // Do nothing.
+ break;
}
std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
@@ -1171,7 +1258,7 @@
annotations = it->second;
}
- int propertyType = expectedPropId & toInt(VehiclePropertyType::MASK);
+ VehiclePropertyType propertyType = getPropertyType(expectedPropId);
verifyPropertyConfigMinMaxValue(config.get(), propertyType);
if (annotations.find(ANNOTATION_REQUIRE_MIN_MAX_VALUE) != annotations.end()) {
verifyPropertyConfigRequireMinMaxValue(config.get(), propertyType);
@@ -1215,6 +1302,7 @@
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveVehicleTargetTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotivePropertyConfigTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveVehicleTargetTest,
testing::ValuesIn(getDescriptors()),
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 3f1f5f6..3d7c376 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -123,40 +123,6 @@
return (sessionType == session_type_);
}
-std::string getSettingOutputString(
- IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting) {
- std::stringstream ss;
- std::string name = "";
- if (!setting.sinkAseConfiguration.has_value() &&
- !setting.sourceAseConfiguration.has_value())
- return "";
- std::vector<
- std::optional<LeAudioAseConfigurationSetting::AseDirectionConfiguration>>*
- directionAseConfiguration;
- if (setting.sinkAseConfiguration.has_value() &&
- !setting.sinkAseConfiguration.value().empty())
- directionAseConfiguration = &setting.sinkAseConfiguration.value();
- else
- directionAseConfiguration = &setting.sourceAseConfiguration.value();
- for (auto& aseConfiguration : *directionAseConfiguration) {
- if (aseConfiguration.has_value() &&
- aseConfiguration.value().aseConfiguration.metadata.has_value()) {
- for (auto& meta :
- aseConfiguration.value().aseConfiguration.metadata.value()) {
- if (meta.has_value() &&
- meta.value().getTag() == MetadataLtv::vendorSpecific) {
- auto k = meta.value().get<MetadataLtv::vendorSpecific>().opaqueValue;
- name = std::string(k.begin(), k.end());
- break;
- }
- }
- }
- }
-
- ss << "setting name: " << name << ", setting: " << setting.toString();
- return ss.str();
-}
-
ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
@@ -742,9 +708,11 @@
return filtered_setting;
}
-std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+std::optional<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
LeAudioOffloadAudioProvider::matchWithRequirement(
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>&
matched_ase_configuration_settings,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
bool isMatchContext, bool isExact, bool isMatchFlags) {
@@ -758,14 +726,15 @@
if (!requirement.flags.has_value()) return std::nullopt;
requirement_flags_bitmask = requirement.flags.value().bitmask;
}
- for (auto& setting : matched_ase_configuration_settings) {
+ for (auto& [setting_name, setting] : matched_ase_configuration_settings) {
// Try to match context.
if (isMatchContext) {
if ((setting.audioContext.bitmask & requirement.audioContext.bitmask) !=
requirement.audioContext.bitmask)
continue;
- LOG(DEBUG) << __func__ << ": Setting with matched context: "
- << getSettingOutputString(setting);
+ LOG(DEBUG) << __func__
+ << ": Setting with matched context: name: " << setting_name
+ << ", setting: " << setting.toString();
}
// Try to match configuration flags
@@ -774,19 +743,20 @@
if ((setting.flags.value().bitmask & requirement_flags_bitmask) !=
requirement_flags_bitmask)
continue;
- LOG(DEBUG) << __func__ << ": Setting with matched flags: "
- << getSettingOutputString(setting);
+ LOG(DEBUG) << __func__
+ << ": Setting with matched flags: name: " << setting_name
+ << ", setting: " << setting.toString();
}
auto filtered_ase_configuration_setting =
getRequirementMatchedAseConfigurationSettings(setting, requirement,
isExact);
if (filtered_ase_configuration_setting.has_value()) {
- LOG(INFO) << __func__ << ": Result found: "
- << getSettingOutputString(
- filtered_ase_configuration_setting.value());
+ LOG(INFO) << __func__ << ": Result found: name: " << setting_name
+ << ", setting: "
+ << filtered_ase_configuration_setting.value().toString();
// Found a matched setting, ignore other settings
- return filtered_ase_configuration_setting;
+ return {{setting_name, filtered_ase_configuration_setting.value()}};
}
}
// If cannot satisfy this requirement, return nullopt
@@ -812,7 +782,8 @@
std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
_aidl_return) {
// Get all configuration settings
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
ase_configuration_settings =
BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
@@ -822,15 +793,17 @@
}
// Matched ASE configuration with ignored audio context
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
sink_matched_ase_configuration_settings;
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
matched_ase_configuration_settings;
// A setting must match both source and sink.
// First filter all setting matched with sink capability
if (in_remoteSinkAudioCapabilities.has_value()) {
- for (auto& setting : ase_configuration_settings) {
+ for (auto& [setting_name, setting] : ase_configuration_settings) {
for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
if (!capability.has_value()) continue;
auto filtered_ase_configuration_setting =
@@ -838,7 +811,7 @@
setting, capability.value(), kLeAudioDirectionSink);
if (filtered_ase_configuration_setting.has_value()) {
sink_matched_ase_configuration_settings.push_back(
- filtered_ase_configuration_setting.value());
+ {setting_name, filtered_ase_configuration_setting.value()});
}
}
}
@@ -848,7 +821,8 @@
// Combine filter every source capability
if (in_remoteSourceAudioCapabilities.has_value()) {
- for (auto& setting : sink_matched_ase_configuration_settings)
+ for (auto& [setting_name, setting] :
+ sink_matched_ase_configuration_settings)
for (auto& capability : in_remoteSourceAudioCapabilities.value()) {
if (!capability.has_value()) continue;
auto filtered_ase_configuration_setting =
@@ -856,7 +830,7 @@
setting, capability.value(), kLeAudioDirectionSource);
if (filtered_ase_configuration_setting.has_value()) {
matched_ase_configuration_settings.push_back(
- filtered_ase_configuration_setting.value());
+ {setting_name, filtered_ase_configuration_setting.value()});
}
}
} else {
@@ -864,7 +838,11 @@
sink_matched_ase_configuration_settings;
}
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ result_no_name;
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
+ result;
for (auto& requirement : in_requirements) {
// For each requirement, try to match with a setting.
// If we cannot match, return an empty result.
@@ -896,18 +874,19 @@
if (!found) {
LOG(ERROR) << __func__
<< ": Cannot find any match for this requirement, exitting...";
- result.clear();
- *_aidl_return = result;
+ *_aidl_return = result_no_name;
return ndk::ScopedAStatus::ok();
}
}
LOG(INFO) << __func__
<< ": Found matches for all requirements, chosen settings:";
- for (auto& setting : result) {
- LOG(INFO) << __func__ << ": " << getSettingOutputString(setting);
+ for (auto& [setting_name, setting] : result) {
+ LOG(INFO) << __func__ << ": name: " << setting_name
+ << ", setting: " << setting.toString();
+ result_no_name.push_back(setting);
}
- *_aidl_return = result;
+ *_aidl_return = result_no_name;
return ndk::ScopedAStatus::ok();
};
@@ -937,7 +916,8 @@
uint8_t direction,
const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
qosRequirement,
- std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings,
+ std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>&
+ ase_configuration_settings,
bool isExact, bool isMatchFlags) {
auto requirement_flags_bitmask = 0;
if (isMatchFlags) {
@@ -955,13 +935,14 @@
direction_qos_requirement = qosRequirement.sourceAseQosRequirement.value();
}
- for (auto& setting : ase_configuration_settings) {
+ for (auto& [setting_name, setting] : ase_configuration_settings) {
// Context matching
if ((setting.audioContext.bitmask & qosRequirement.audioContext.bitmask) !=
qosRequirement.audioContext.bitmask)
continue;
- LOG(DEBUG) << __func__ << ": Setting with matched context: "
- << getSettingOutputString(setting);
+ LOG(DEBUG) << __func__
+ << ": Setting with matched context: name: " << setting_name
+ << ", setting: " << setting.toString();
// Match configuration flags
if (isMatchFlags) {
@@ -969,8 +950,9 @@
if ((setting.flags.value().bitmask & requirement_flags_bitmask) !=
requirement_flags_bitmask)
continue;
- LOG(DEBUG) << __func__ << ": Setting with matched flags: "
- << getSettingOutputString(setting);
+ LOG(DEBUG) << __func__
+ << ": Setting with matched flags: name: " << setting_name
+ << ", setting: " << setting.toString();
}
// Get a list of all matched AseDirectionConfiguration
@@ -1041,7 +1023,8 @@
IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
// Get all configuration settings
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::vector<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
ase_configuration_settings =
BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 8c4f543..6d402a4 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -163,15 +163,19 @@
uint8_t direction,
const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
qosRequirement,
- std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings,
+ std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>&
+ ase_configuration_settings,
bool isExact, bool isMatchedFlag);
bool isSubgroupConfigurationMatchedContext(
AudioContext requirement_context,
IBluetoothAudioProvider::BroadcastQuality quality,
LeAudioBroadcastSubgroupConfiguration configuration);
- std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::optional<std::pair<
+ std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
matchWithRequirement(
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
+ std::vector<
+ std::pair<std::string,
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>&
matched_ase_configuration_settings,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
requirements,
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index db2528e..89472e6 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -452,7 +452,7 @@
return kDefaultOffloadHfpCodecInfo;
}
-std::vector<LeAudioAseConfigurationSetting>
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
return AudioSetConfigurationProviderJson::
GetLeAudioAseConfigurationSettings();
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index 0a1f708..c77de61 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -54,7 +54,7 @@
static std::vector<CodecInfo> GetLeAudioOffloadCodecInfo(
const SessionType& session_type);
- static std::vector<LeAudioAseConfigurationSetting>
+ static std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
GetLeAudioAseConfigurationSettings();
static std::vector<CodecInfo> GetHfpOffloadCodecInfo();
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
index 2474916..feb4cda 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
@@ -65,7 +65,8 @@
ConfigurationFlags>>
configurations_;
-std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
+ ase_configuration_settings_;
constexpr uint8_t kIsoDataPathHci = 0x00;
constexpr uint8_t kIsoDataPathPlatformDefault = 0x01;
@@ -273,7 +274,7 @@
/* Implementation */
-std::vector<LeAudioAseConfigurationSetting>
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {
AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson();
return ase_configuration_settings_;
@@ -392,7 +393,7 @@
}
void AudioSetConfigurationProviderJson::populateAseConfiguration(
- const std::string& name, LeAudioAseConfiguration& ase,
+ LeAudioAseConfiguration& ase,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg,
ConfigurationFlags& configurationFlags) {
@@ -431,12 +432,6 @@
}
// Codec configuration data
populateConfigurationData(ase, flat_subconfig->codec_configuration());
- // Populate the config name for easier debug
- auto meta = std::vector<std::optional<MetadataLtv>>();
- MetadataLtv::VendorSpecific cfg_name;
- cfg_name.opaqueValue = std::vector<uint8_t>(name.begin(), name.end());
- meta.push_back(cfg_name);
- ase.metadata = meta;
}
void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
@@ -507,7 +502,6 @@
// Parse into AseDirectionConfiguration
AseDirectionConfiguration
AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
- const std::string& name,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg, CodecLocation location,
ConfigurationFlags& configurationFlags) {
@@ -518,8 +512,7 @@
LeAudioDataPathConfiguration path;
// Translate into LeAudioAseConfiguration
- populateAseConfiguration(name, ase, flat_subconfig, qos_cfg,
- configurationFlags);
+ populateAseConfiguration(ase, flat_subconfig, qos_cfg, configurationFlags);
// Translate into LeAudioAseQosConfiguration
populateAseQosConfiguration(qos, qos_cfg, ase,
@@ -553,15 +546,14 @@
// Parse into AseDirectionConfiguration and the ConfigurationFlags
// and put them in the given list.
void AudioSetConfigurationProviderJson::processSubconfig(
- const std::string& name,
const le_audio::AudioSetSubConfiguration* subconfig,
const le_audio::QosConfiguration* qos_cfg,
std::vector<std::optional<AseDirectionConfiguration>>&
directionAseConfiguration,
CodecLocation location, ConfigurationFlags& configurationFlags) {
auto ase_cnt = subconfig->ase_cnt();
- auto config = SetConfigurationFromFlatSubconfig(name, subconfig, qos_cfg,
- location, configurationFlags);
+ auto config = SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location,
+ configurationFlags);
directionAseConfiguration.push_back(config);
// Put the same setting again.
if (ase_cnt == 2) directionAseConfiguration.push_back(config);
@@ -646,11 +638,11 @@
/* Load subconfigurations */
for (auto subconfig : *codec_cfg->subconfigurations()) {
if (subconfig->direction() == kLeAudioDirectionSink) {
- processSubconfig(flat_cfg->name()->str(), subconfig, qos_sink_cfg,
- sinkAseConfiguration, location, configurationFlags);
+ processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration,
+ location, configurationFlags);
} else {
- processSubconfig(flat_cfg->name()->str(), subconfig, qos_source_cfg,
- sourceAseConfiguration, location, configurationFlags);
+ processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration,
+ location, configurationFlags);
}
}
@@ -860,7 +852,7 @@
setting.flags = flags;
// Add to list of setting
LOG(DEBUG) << "Pushing configuration to list: " << config_name;
- ase_configuration_settings_.push_back(setting);
+ ase_configuration_settings_.push_back({config_name, setting});
}
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
index 8e12618..f115d61 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
@@ -50,7 +50,7 @@
class AudioSetConfigurationProviderJson {
public:
- static std::vector<LeAudioAseConfigurationSetting>
+ static std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
GetLeAudioAseConfigurationSettings();
private:
@@ -73,7 +73,7 @@
flat_codec_specific_params);
static void populateAseConfiguration(
- const std::string& name, LeAudioAseConfiguration& ase,
+ LeAudioAseConfiguration& ase,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg,
ConfigurationFlags& configurationFlags);
@@ -84,13 +84,11 @@
uint8_t ase_channel_cnt);
static AseDirectionConfiguration SetConfigurationFromFlatSubconfig(
- const std::string& name,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg, CodecLocation location,
ConfigurationFlags& configurationFlags);
static void processSubconfig(
- const std::string& name,
const le_audio::AudioSetSubConfiguration* subconfig,
const le_audio::QosConfiguration* qos_cfg,
std::vector<std::optional<AseDirectionConfiguration>>&
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index cf9c6d7..6ff51bf 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -36,6 +36,7 @@
srcs: [
"VtsHalGraphicsComposer3_TargetTest.cpp",
"VtsHalGraphicsComposer3_ReadbackTest.cpp",
+ "VtsHalGraphicsComposer3_ConnectedDisplays.cpp",
],
shared_libs: [
"libEGL",
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp
new file mode 100644
index 0000000..dff1fa5
--- /dev/null
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2025, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <android-base/properties.h>
+#include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <string>
+#include <unordered_map>
+#include "ComposerClientWrapper.h"
+
+#undef LOG_TAG
+#define LOG_TAG "VtsHalGraphicsComposer3_ConnectedDisplays"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using namespace std::chrono_literals;
+using namespace aidl::android::hardware::graphics::composer3::libhwc_aidl_test;
+
+/**
+ * @class ConnectedDisplaysTest
+ * @brief A test suite for validating the HWC (Hardware Composer) API when multiple displays are
+ * present.
+ *
+ * This test suite is part of the VTS (Vendor Test Suite) and is designed to test the interactions
+ * between multiple displays using the HWC API. It ensures that the API behaves correctly when more
+ * than one display are present.
+ *
+ * @note The test requires at least two displays to be found. If only one display is found, the test
+ * will be skipped.
+ */
+class ConnectedDisplaysTest : public ::testing::TestWithParam<std::string> {
+ protected:
+ void SetUp() override {
+ mComposerClient = std::make_unique<ComposerClientWrapper>(GetParam());
+ ASSERT_TRUE(mComposerClient->createClient().isOk());
+
+ const auto& [status, displays] = mComposerClient->getDisplays();
+ ASSERT_TRUE(status.isOk());
+ mDisplays = displays;
+
+ // Skip test if there's only one display
+ if (mDisplays.size() <= 1) {
+ GTEST_SKIP() << "Test requires at least 2 displays, found " << mDisplays.size();
+ }
+
+ // explicitly disable vsync for all displays
+ for (const auto& display : mDisplays) {
+ EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), false).isOk());
+ }
+ mComposerClient->setVsyncAllowed(false);
+ }
+
+ void TearDown() override {
+ ASSERT_TRUE(
+ mComposerClient->tearDown(std::unordered_map<int64_t, ComposerClientWriter*>{}));
+ mComposerClient.reset();
+ }
+
+ std::unique_ptr<ComposerClientWrapper> mComposerClient;
+ std::vector<DisplayWrapper> mDisplays;
+ static constexpr uint32_t kBufferSlotCount = 64;
+};
+
+/**
+ * Test that verifies display configurations can be changed independently without affecting other
+ * displays.
+ */
+TEST_P(ConnectedDisplaysTest, IndependentConfigChange) {
+ // Store initial configs for all displays
+ std::unordered_map<int64_t, int32_t> initialConfigs;
+ for (const auto& display : mDisplays) {
+ const auto& [activeStatus, activeConfig] =
+ mComposerClient->getActiveConfig(display.getDisplayId());
+ ASSERT_TRUE(activeStatus.isOk());
+ initialConfigs[display.getDisplayId()] = activeConfig;
+ }
+
+ for (auto& display : mDisplays) {
+ const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
+ ASSERT_TRUE(status.isOk());
+ ASSERT_FALSE(configs.empty());
+
+ // Try to set each config
+ for (const auto& config : configs) {
+ if (config == initialConfigs[display.getDisplayId()]) continue;
+
+ EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
+
+ // Verify other displays' configs remain unchanged
+ for (const auto& otherDisplay : mDisplays) {
+ if (otherDisplay.getDisplayId() != display.getDisplayId()) {
+ const auto& [otherStatus, otherConfig] =
+ mComposerClient->getActiveConfig(otherDisplay.getDisplayId());
+ EXPECT_TRUE(otherStatus.isOk());
+ EXPECT_EQ(otherConfig, initialConfigs[otherDisplay.getDisplayId()]);
+ }
+ }
+ }
+ // Restore original config
+ EXPECT_TRUE(
+ mComposerClient->setActiveConfig(&display, initialConfigs[display.getDisplayId()])
+ .isOk());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConnectedDisplaysTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, ConnectedDisplaysTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/nfc/OWNERS b/nfc/OWNERS
index f46dccd..47f209f 100644
--- a/nfc/OWNERS
+++ b/nfc/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
+include platform/packages/modules/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
index 6db7e14..9c44c3a 100644
--- a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
+++ b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
@@ -349,44 +349,18 @@
}
/*
- * SetPassiveObserverTech_individualTechnologies:
- * Verifies per-technology observe mode is supported as a capability. Then sets observe mode
- * for each individual technology and verifies the command succeeds.
- *
- * @VsrTest = GMS-VSR-3.2.8-002
+ * SetPassiveObserverTech_getCaps:
+ * Verifies GET_CAPS returns get correct value for observe mode capabilities.
*/
-TEST_P(NfcBehaviorChanges, SetPassiveObserverTech_individualTechnologies) {
+TEST_P(NfcBehaviorChanges, SetPassiveObserverTech_getCaps) {
if (get_vsr_api_level() < 202504) {
GTEST_SKIP() << "Skipping test for board API level < 202504";
}
tNFC_STATUS status = nfaGetCaps();
+
ASSERT_EQ(status, NFC_STATUS_OK);
ASSERT_EQ(getCapsPassiveObserverModeValue(), 0x2);
-
- status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_A);
- ASSERT_EQ(status, NFA_STATUS_OK);
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_A);
-
- status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_B);
- ASSERT_EQ(status, NFA_STATUS_OK);
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_B);
-
- status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_V);
- ASSERT_EQ(status, NFA_STATUS_OK);
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_V);
-
- status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_F);
- ASSERT_EQ(status, NFA_STATUS_OK);
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_F);
}
/*
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 87797ae..93b7c38 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -317,6 +317,9 @@
}
ASSERT_TRUE(ret.isOk());
ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
+ ASSERT_LE(mSupportInfo->headroom.cpuMinCalculationWindowMillis, 50);
+ ASSERT_GE(mSupportInfo->headroom.cpuMaxCalculationWindowMillis, 10000);
+ ASSERT_GE(mSupportInfo->headroom.cpuMaxTidCount, 5);
ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
@@ -335,6 +338,8 @@
}
ASSERT_TRUE(ret.isOk());
ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
+ ASSERT_LE(mSupportInfo->headroom.gpuMinCalculationWindowMillis, 50);
+ ASSERT_GE(mSupportInfo->headroom.gpuMaxCalculationWindowMillis, 10000);
ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index c6b2579..98ea0d2 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -55,6 +55,15 @@
ASSERT_NE(nullptr, radio_config.get());
}
+bool RadioModemTest::shouldTestCdma() {
+ int32_t aidl_version = 0;
+ ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+ EXPECT_TRUE(aidl_status.isOk());
+ if (aidl_version < 2) return true; // < RADIO_HAL_VERSION_2_1
+
+ return !telephony_flags::cleanup_cdma();
+}
+
/*
* Test IRadioModem.setRadioPower() for the response returned.
*/
@@ -244,6 +253,10 @@
* Test IRadioModem.nvReadItem() for the response returned.
*/
TEST_P(RadioModemTest, nvReadItem) {
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+ }
+
serial = GetRandomSerialNumber();
radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
@@ -261,6 +274,10 @@
* Test IRadioModem.nvWriteItem() for the response returned.
*/
TEST_P(RadioModemTest, nvWriteItem) {
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+ }
+
serial = GetRandomSerialNumber();
NvWriteItem item;
memset(&item, 0, sizeof(item));
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index aa99ea3..21481bd 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -119,6 +119,8 @@
public:
void SetUp() override;
+ bool shouldTestCdma();
+
/* radio modem service handle */
std::shared_ptr<IRadioModem> radio_modem;
/* radio modem response handle */
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 9a3a429..439d268 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -78,6 +78,15 @@
ASSERT_NE(nullptr, radio_config.get());
}
+bool RadioNetworkTest::shouldTestCdma() {
+ int32_t aidl_version = 0;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ EXPECT_TRUE(aidl_status.isOk());
+ if (aidl_version < 4) return true; // < RADIO_HAL_VERSION_2_3
+
+ return !telephony_flags::cleanup_cdma();
+}
+
void RadioNetworkTest::stopNetworkScan() {
serial = GetRandomSerialNumber();
radio_network->stopNetworkScan(serial);
@@ -1775,6 +1784,9 @@
* Test IRadioNetwork.getAvailableBandModes() for the response returned.
*/
TEST_P(RadioNetworkTest, getAvailableBandModes) {
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+ }
if (telephony_flags::enforce_telephony_feature_mapping()) {
if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
GTEST_SKIP() << "Skipping getAvailableBandModes "
@@ -2019,6 +2031,9 @@
* Test IRadioNetwork.setBandMode() for the response returned.
*/
TEST_P(RadioNetworkTest, setBandMode) {
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+ }
if (telephony_flags::enforce_telephony_feature_mapping()) {
if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
GTEST_SKIP() << "Skipping setBandMode "
@@ -2043,6 +2058,10 @@
* Test IRadioNetwork.setLocationUpdates() for the response returned.
*/
TEST_P(RadioNetworkTest, setLocationUpdates) {
+ // While setLocationUpdates is not CDMA-related, it's guarded by the same release flag.
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping testing of deprecated setLocationUpdates method";
+ }
if (telephony_flags::enforce_telephony_feature_mapping()) {
if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
GTEST_SKIP() << "Skipping setLocationUpdates "
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 17c0896..3387dec 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -263,6 +263,8 @@
public:
void SetUp() override;
+ bool shouldTestCdma();
+
/* radio network service handle */
std::shared_ptr<IRadioNetwork> radio_network;
/* radio network response handle */
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 2823977..aaccb21 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -52,6 +52,15 @@
ASSERT_NE(nullptr, radio_config.get());
}
+bool RadioSimTest::shouldTestCdma() {
+ int32_t aidl_version = 0;
+ ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+ EXPECT_TRUE(aidl_status.isOk());
+ if (aidl_version < 4) return true; // < RADIO_HAL_VERSION_2_3
+
+ return !telephony_flags::cleanup_cdma();
+}
+
void RadioSimTest::updateSimCardStatus() {
serial = GetRandomSerialNumber();
radio_sim->getIccCardStatus(serial);
@@ -935,6 +944,13 @@
* Test IRadioSim.iccCloseLogicalChannel() for the response returned.
*/
TEST_P(RadioSimTest, iccCloseLogicalChannel) {
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+ if (aidl_version >= 2) { // >= RADIO_HAL_VERSION_2_1
+ GTEST_SKIP() << "Skipping iccCloseLogicalChannel (deprecated)";
+ }
+
if (telephony_flags::enforce_telephony_feature_mapping()) {
if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
GTEST_SKIP() << "Skipping iccCloseLogicalChannel "
@@ -1176,6 +1192,9 @@
* Test IRadioSim.setUiccSubscription() for the response returned.
*/
TEST_P(RadioSimTest, setUiccSubscription) {
+ if (!shouldTestCdma()) {
+ GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+ }
if (telephony_flags::enforce_telephony_feature_mapping()) {
if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
GTEST_SKIP() << "Skipping setUiccSubscription "
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index 7cbcc58..eb3efb2 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -198,6 +198,8 @@
public:
void SetUp() override;
+ bool shouldTestCdma();
+
/* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */
void updateSimCardStatus();
diff --git a/security/see/authmgr/aidl/README.md b/security/see/authmgr/aidl/README.md
new file mode 100644
index 0000000..97b2b1d
--- /dev/null
+++ b/security/see/authmgr/aidl/README.md
@@ -0,0 +1,21 @@
+# AuthMgr
+
+The AuthMgr protocol authenticates and authorizes clients before they can
+access trusted HALs, AIDL-defined services in trusted execution environments.
+Version 1 was designed to allow applications running in a protected virtual
+machine (pVM) to access services running in a TEE in ARM TrustZone. An
+implementation of `IAuthMgrAuthorization` is referred to as an AuthMgr Backend.
+An implementation of a client of the AuthMgr Backend is referred to as an
+AuthMgr Frontend.
+
+
+## Additional Requirements by Android Version
+
+The comments on `IAuthMgrAuthorization` describe the requirements for implementing
+an AuthMgr Backend (implementor of the interface) itself. There are some additional
+requirements that are specific to Android release versions.
+
+### Android 16
+If implementing `IAuthMgrAuthorization` in Android 16 only one AuthMgr Backend is
+supported and dynamic service discovery is not supported. The AuthMgr Backend
+service must be exposed on secure partition ID 0x8001 over VSOCK port 1.
\ No newline at end of file