Merge "Check for AP support in the VTS test before creating an AP iface." into main
diff --git a/Android.bp b/Android.bp
index baf3291..223a1a9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,7 @@
// Lists all dependencies that can *not* be expected on the device.
static_libs: [
"VtsHalHidlTestUtils",
+ "libhidlbase",
"libhidl-gen-utils",
],
@@ -63,7 +64,6 @@
"libbase",
// All the following are dependencies of any HAL definition library.
"libcutils",
- "libhidlbase",
"liblog",
"libutils",
],
@@ -72,6 +72,14 @@
"-g",
],
+ target: {
+ android: {
+ shared_libs: [
+ "libvndksupport",
+ ],
+ },
+ },
+
require_root: true,
}
diff --git a/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
index c92e852..4170b4c 100644
--- a/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
+++ b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
@@ -33,6 +33,6 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="{MODULE}" />
- <option name="native-test-timeout" value="10m" />
+ <option name="native-test-timeout" value="30m" />
</test>
</configuration>
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 82a194e..e31aae6 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -353,8 +353,14 @@
mInput.resize(kBufferSize);
generateSineWaveInput(mInput);
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
void assertEnergyIncreasingWithParameter(bool bypass) {
createEnvParam(EnvironmentalReverb::bypass, bypass);
@@ -418,12 +424,16 @@
std::tie(mTag, mValue) = std::get<TAG_VALUE_PAIR>(GetParam());
}
void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
SetUpReverb();
createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
ASSERT_NO_FATAL_FAILURE(
setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
}
- void TearDown() override { TearDownReverb(); }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
EnvironmentalReverb::Tag mTag;
int mValue;
@@ -469,8 +479,14 @@
mInput.resize(kBufferSize);
generateSineWaveInput(mInput);
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
float getMean(std::vector<float>& buffer) {
return std::accumulate(buffer.begin(), buffer.end(), 0.0) / buffer.size();
@@ -543,8 +559,14 @@
generateSineWaveInput(mInput);
}
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
EnvironmentalReverb::Tag mTag;
int mParamValues;
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 477de31..dc78ed6 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -317,12 +317,20 @@
// Verify methods for extended info
const auto id = 0xFFFFFFFF; // meaningless id
std::vector<uint8_t> values;
+ bool isSupported = false;
auto status = pCam->setExtendedInfo(id, values);
if (isLogicalCam) {
EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
static_cast<int>(EvsResult::NOT_SUPPORTED));
} else {
- EXPECT_TRUE(status.isOk());
+ if (status.isOk()) {
+ // 0xFFFFFFFF is valid for EVS HAL implementation under
+ // test.
+ isSupported = true;
+ } else {
+ EXPECT_TRUE(status.getServiceSpecificError() ==
+ static_cast<int>(EvsResult::INVALID_ARG));
+ }
}
status = pCam->getExtendedInfo(id, &values);
@@ -330,7 +338,12 @@
EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
static_cast<int>(EvsResult::NOT_SUPPORTED));
} else {
- EXPECT_TRUE(status.isOk());
+ if (isSupported) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
+ static_cast<int>(EvsResult::INVALID_ARG));
+ }
}
// Explicitly close the camera so resources are released right away
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
index eb98af0..d7cbe1b 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
@@ -69,10 +69,13 @@
const proto::VehiclePropValueRequests* requests,
proto::SetValueResults* results) {
std::vector<aidlvhal::SetValueRequest> aidlRequests;
+ std::unordered_set<int64_t> requestIds;
for (const auto& protoRequest : requests->requests()) {
auto& aidlRequest = aidlRequests.emplace_back();
- aidlRequest.requestId = protoRequest.request_id();
+ int64_t requestId = protoRequest.request_id();
+ aidlRequest.requestId = requestId;
proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.value);
+ requestIds.insert(requestId);
}
auto waitMtx = std::make_shared<std::mutex>();
auto waitCV = std::make_shared<std::condition_variable>();
@@ -80,19 +83,27 @@
auto tmpResults = std::make_shared<proto::SetValueResults>();
auto aidlStatus = mHardware->setValues(
std::make_shared<const IVehicleHardware::SetValuesCallback>(
- [waitMtx, waitCV, complete,
- tmpResults](std::vector<aidlvhal::SetValueResult> setValueResults) {
- for (const auto& aidlResult : setValueResults) {
- auto& protoResult = *tmpResults->add_results();
- protoResult.set_request_id(aidlResult.requestId);
- protoResult.set_status(
- static_cast<proto::StatusCode>(aidlResult.status));
- }
+ [waitMtx, waitCV, complete, tmpResults,
+ &requestIds](std::vector<aidlvhal::SetValueResult> setValueResults) {
+ bool receivedAllResults = false;
{
std::lock_guard lck(*waitMtx);
- *complete = true;
+ for (const auto& aidlResult : setValueResults) {
+ auto& protoResult = *tmpResults->add_results();
+ int64_t requestIdForResult = aidlResult.requestId;
+ protoResult.set_request_id(requestIdForResult);
+ protoResult.set_status(
+ static_cast<proto::StatusCode>(aidlResult.status));
+ requestIds.erase(requestIdForResult);
+ }
+ if (requestIds.empty()) {
+ receivedAllResults = true;
+ *complete = true;
+ }
}
- waitCV->notify_all();
+ if (receivedAllResults) {
+ waitCV->notify_all();
+ }
}),
aidlRequests);
if (aidlStatus != aidlvhal::StatusCode::OK) {
@@ -114,10 +125,13 @@
const proto::VehiclePropValueRequests* requests,
proto::GetValueResults* results) {
std::vector<aidlvhal::GetValueRequest> aidlRequests;
+ std::unordered_set<int64_t> requestIds;
for (const auto& protoRequest : requests->requests()) {
auto& aidlRequest = aidlRequests.emplace_back();
- aidlRequest.requestId = protoRequest.request_id();
+ int64_t requestId = protoRequest.request_id();
+ aidlRequest.requestId = requestId;
proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.prop);
+ requestIds.insert(requestId);
}
auto waitMtx = std::make_shared<std::mutex>();
auto waitCV = std::make_shared<std::condition_variable>();
@@ -125,23 +139,31 @@
auto tmpResults = std::make_shared<proto::GetValueResults>();
auto aidlStatus = mHardware->getValues(
std::make_shared<const IVehicleHardware::GetValuesCallback>(
- [waitMtx, waitCV, complete,
- tmpResults](std::vector<aidlvhal::GetValueResult> getValueResults) {
- for (const auto& aidlResult : getValueResults) {
- auto& protoResult = *tmpResults->add_results();
- protoResult.set_request_id(aidlResult.requestId);
- protoResult.set_status(
- static_cast<proto::StatusCode>(aidlResult.status));
- if (aidlResult.prop) {
- auto* valuePtr = protoResult.mutable_value();
- proto_msg_converter::aidlToProto(*aidlResult.prop, valuePtr);
- }
- }
+ [waitMtx, waitCV, complete, tmpResults,
+ &requestIds](std::vector<aidlvhal::GetValueResult> getValueResults) {
+ bool receivedAllResults = false;
{
std::lock_guard lck(*waitMtx);
- *complete = true;
+ for (const auto& aidlResult : getValueResults) {
+ auto& protoResult = *tmpResults->add_results();
+ int64_t requestIdForResult = aidlResult.requestId;
+ protoResult.set_request_id(requestIdForResult);
+ protoResult.set_status(
+ static_cast<proto::StatusCode>(aidlResult.status));
+ if (aidlResult.prop) {
+ auto* valuePtr = protoResult.mutable_value();
+ proto_msg_converter::aidlToProto(*aidlResult.prop, valuePtr);
+ }
+ requestIds.erase(requestIdForResult);
+ }
+ if (requestIds.empty()) {
+ receivedAllResults = true;
+ *complete = true;
+ }
}
- waitCV->notify_all();
+ if (receivedAllResults) {
+ waitCV->notify_all();
+ }
}),
aidlRequests);
if (aidlStatus != aidlvhal::StatusCode::OK) {
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index fa2a310..b58d0f5 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -31,6 +31,7 @@
#include <android-base/thread_annotations.h>
#include <android/binder_auto_utils.h>
+#include <functional>
#include <memory>
#include <mutex>
#include <shared_mutex>
@@ -138,12 +139,11 @@
// Only used for testing.
int32_t mTestInterfaceVersion = 0;
- // mConfigsByPropId and mConfigFile is lazy initialized.
- mutable std::mutex mConfigInitLock;
- mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false;
+ mutable std::atomic<bool> mConfigInit = false;
+ mutable std::shared_timed_mutex mConfigLock;
mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
- GUARDED_BY(mConfigInitLock);
- mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock);
+ GUARDED_BY(mConfigLock);
+ mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigLock);
std::mutex mLock;
std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@@ -175,7 +175,10 @@
android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
const std::vector<aidlvhal::SetValueRequest>& requests);
- VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options);
+ VhalResult<void> checkSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId)
+ REQUIRES_SHARED(mConfigLock);
VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
aidlvhal::VehiclePropertyAccess accessToTest) const;
@@ -184,7 +187,7 @@
VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
- android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const;
+ android::base::Result<aidlvhal::VehiclePropConfig> getConfig(int32_t propId) const;
void onBinderDiedWithContext(const AIBinder* clientId);
@@ -196,7 +199,7 @@
bool checkDumpPermission();
- bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock);
+ bool getAllPropConfigsFromHardwareLocked() const EXCLUDES(mConfigLock);
// The looping handler function to process all onBinderDied or onBinderUnlinked events in
// mBinderEvents.
@@ -209,10 +212,12 @@
int32_t getVhalInterfaceVersion() const;
- // Gets mConfigsByPropId, lazy init it if necessary.
- const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const;
- // Gets mConfigFile, lazy init it if necessary.
- const ndk::ScopedFileDescriptor* getConfigFile() const;
+ // Gets mConfigsByPropId, lazy init it if necessary. Note that the reference is only valid in
+ // the scope of the callback and it is guaranteed that read lock is obtained during the
+ // callback.
+ void getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
+ callback) const EXCLUDES(mConfigLock);
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
@@ -239,6 +244,12 @@
static void onBinderUnlinked(void* cookie);
+ static void parseSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId,
+ std::vector<aidlvhal::SubscribeOptions>& onChangeSubscriptions,
+ std::vector<aidlvhal::SubscribeOptions>& continuousSubscriptions);
+
// Test-only
// Set the default timeout for pending requests.
void setTimeout(int64_t timeoutInNano);
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 9dc039d..e062a28 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -95,6 +95,18 @@
return sampleRateHz;
}
+class SCOPED_CAPABILITY SharedScopedLockAssertion {
+ public:
+ SharedScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE_SHARED(mutex) {}
+ ~SharedScopedLockAssertion() RELEASE() {}
+};
+
+class SCOPED_CAPABILITY UniqueScopedLockAssertion {
+ public:
+ UniqueScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE(mutex) {}
+ ~UniqueScopedLockAssertion() RELEASE() {}
+};
+
} // namespace
DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
@@ -355,68 +367,82 @@
}
filteredConfigs.push_back(std::move(config));
}
- for (auto& config : filteredConfigs) {
- mConfigsByPropId[config.prop] = config;
- }
- VehiclePropConfigs vehiclePropConfigs;
- vehiclePropConfigs.payloads = std::move(filteredConfigs);
- auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
- if (!result.ok()) {
- ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
- result.error().message().c_str(), static_cast<int>(result.error().code()));
- mConfigFile = nullptr;
- return false;
+
+ {
+ std::unique_lock<std::shared_timed_mutex> configWriteLock(mConfigLock);
+ UniqueScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (auto& config : filteredConfigs) {
+ mConfigsByPropId[config.prop] = config;
+ }
+ VehiclePropConfigs vehiclePropConfigs;
+ vehiclePropConfigs.payloads = std::move(filteredConfigs);
+ auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
+ if (!result.ok()) {
+ ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+ result.error().message().c_str(), static_cast<int>(result.error().code()));
+ mConfigFile = nullptr;
+ return false;
+ }
+
+ if (result.value() != nullptr) {
+ mConfigFile = std::move(result.value());
+ }
}
- if (result.value() != nullptr) {
- mConfigFile = std::move(result.value());
- }
+ mConfigInit = true;
return true;
}
-const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const {
- std::scoped_lock lockGuard(mConfigInitLock);
+void DefaultVehicleHal::getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, VehiclePropConfig>&)> callback) const {
if (!mConfigInit) {
CHECK(getAllPropConfigsFromHardwareLocked())
<< "Failed to get property configs from hardware";
- mConfigInit = true;
}
- return mConfigFile.get();
-}
-const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId()
- const {
- std::scoped_lock lockGuard(mConfigInitLock);
- if (!mConfigInit) {
- CHECK(getAllPropConfigsFromHardwareLocked())
- << "Failed to get property configs from hardware";
- mConfigInit = true;
- }
- return mConfigsByPropId;
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ callback(mConfigsByPropId);
}
ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
- const ScopedFileDescriptor* configFile = getConfigFile();
- const auto& configsByPropId = getConfigsByPropId();
- if (configFile != nullptr) {
+ if (!mConfigInit) {
+ CHECK(getAllPropConfigsFromHardwareLocked())
+ << "Failed to get property configs from hardware";
+ }
+
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (mConfigFile != nullptr) {
output->payloads.clear();
- output->sharedMemoryFd.set(dup(configFile->get()));
+ output->sharedMemoryFd.set(dup(mConfigFile->get()));
return ScopedAStatus::ok();
}
- output->payloads.reserve(configsByPropId.size());
- for (const auto& [_, config] : configsByPropId) {
+
+ output->payloads.reserve(mConfigsByPropId.size());
+ for (const auto& [_, config] : mConfigsByPropId) {
output->payloads.push_back(config);
}
return ScopedAStatus::ok();
}
-Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const {
- const auto& configsByPropId = getConfigsByPropId();
- auto it = configsByPropId.find(propId);
- if (it == configsByPropId.end()) {
- return Error() << "no config for property, ID: " << propId;
- }
- return &(it->second);
+Result<VehiclePropConfig> DefaultVehicleHal::getConfig(int32_t propId) const {
+ Result<VehiclePropConfig> result;
+ getConfigsByPropId([this, &result, propId](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ auto it = configsByPropId.find(propId);
+ if (it == configsByPropId.end()) {
+ result = Error() << "no config for property, ID: " << propId;
+ return;
+ }
+ // Copy the VehiclePropConfig
+ result = it->second;
+ });
+ return result;
}
Result<void> DefaultVehicleHal::checkProperty(const VehiclePropValue& propValue) {
@@ -425,15 +451,15 @@
if (!result.ok()) {
return result.error();
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
if (!isGlobalProp(propId) && areaConfig == nullptr) {
// Ignore areaId for global property. For non global property, check whether areaId is
// allowed. areaId must appear in areaConfig.
return Error() << "invalid area ID: " << propValue.areaId << " for prop ID: " << propId
<< ", not listed in config";
}
- if (auto result = checkPropValue(propValue, config); !result.ok()) {
+ if (auto result = checkPropValue(propValue, &config); !result.ok()) {
return Error() << "invalid property value: " << propValue.toString()
<< ", error: " << getErrorMsg(result);
}
@@ -659,17 +685,27 @@
ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
VehiclePropConfigs* output) {
std::vector<VehiclePropConfig> configs;
- const auto& configsByPropId = getConfigsByPropId();
- for (int32_t prop : props) {
- auto it = configsByPropId.find(prop);
- if (it != configsByPropId.end()) {
- configs.push_back(it->second);
- } else {
- return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- toInt(StatusCode::INVALID_ARG),
- StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ ScopedAStatus status = ScopedAStatus::ok();
+ getConfigsByPropId([this, &configs, &status, &props](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (int32_t prop : props) {
+ auto it = configsByPropId.find(prop);
+ if (it != configsByPropId.end()) {
+ configs.push_back(it->second);
+ } else {
+ status = ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(StatusCode::INVALID_ARG),
+ StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ return;
+ }
}
+ });
+
+ if (!status.isOk()) {
+ return status;
}
+
return vectorToStableLargeParcelable(std::move(configs), output);
}
@@ -691,8 +727,8 @@
}
VhalResult<void> DefaultVehicleHal::checkSubscribeOptions(
- const std::vector<SubscribeOptions>& options) {
- const auto& configsByPropId = getConfigsByPropId();
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId) {
for (const auto& option : options) {
int32_t propId = option.propId;
auto it = configsByPropId.find(propId);
@@ -757,23 +793,15 @@
}
}
}
+
return {};
}
-ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
- const std::vector<SubscribeOptions>& options,
- [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
- // TODO(b/205189110): Use shared memory file count.
- if (callback == nullptr) {
- return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
- }
- if (auto result = checkSubscribeOptions(options); !result.ok()) {
- ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
- return toScopedAStatus(result);
- }
- std::vector<SubscribeOptions> onChangeSubscriptions;
- std::vector<SubscribeOptions> continuousSubscriptions;
- const auto& configsByPropId = getConfigsByPropId();
+void DefaultVehicleHal::parseSubscribeOptions(
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId,
+ std::vector<SubscribeOptions>& onChangeSubscriptions,
+ std::vector<SubscribeOptions>& continuousSubscriptions) {
for (const auto& option : options) {
int32_t propId = option.propId;
// We have already validate config exists.
@@ -831,6 +859,34 @@
onChangeSubscriptions.push_back(std::move(optionCopy));
}
}
+}
+
+ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
+ const std::vector<SubscribeOptions>& options,
+ [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
+ // TODO(b/205189110): Use shared memory file count.
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
+ std::vector<SubscribeOptions> onChangeSubscriptions;
+ std::vector<SubscribeOptions> continuousSubscriptions;
+ ScopedAStatus returnStatus = ScopedAStatus::ok();
+ getConfigsByPropId([this, &returnStatus, &options, &onChangeSubscriptions,
+ &continuousSubscriptions](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (auto result = checkSubscribeOptions(options, configsByPropId); !result.ok()) {
+ ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
+ returnStatus = toScopedAStatus(result);
+ return;
+ }
+ parseSubscribeOptions(options, configsByPropId, onChangeSubscriptions,
+ continuousSubscriptions);
+ });
+
+ if (!returnStatus.isOk()) {
+ return returnStatus;
+ }
{
// Lock to make sure onBinderDied would not be called concurrently.
@@ -891,13 +947,13 @@
return StatusError(StatusCode::INVALID_ARG) << getErrorMsg(result);
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(value, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(value, config);
if (areaConfig == nullptr && !isGlobalProp(propId)) {
return StatusError(StatusCode::INVALID_ARG) << "no config for area ID: " << value.areaId;
}
- if (!hasRequiredAccess(config->access, accessToTest) &&
+ if (!hasRequiredAccess(config.access, accessToTest) &&
(areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) {
return StatusError(StatusCode::ACCESS_DENIED)
<< StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32,
@@ -966,7 +1022,6 @@
}
DumpResult result = mVehicleHardware->dump(options);
if (result.refreshPropertyConfigs) {
- std::scoped_lock lockGuard(mConfigInitLock);
getAllPropConfigsFromHardwareLocked();
}
dprintf(fd, "%s", (result.buffer + "\n").c_str());
@@ -974,11 +1029,16 @@
return STATUS_OK;
}
dprintf(fd, "Vehicle HAL State: \n");
- const auto& configsByPropId = getConfigsByPropId();
+ std::unordered_map<int32_t, VehiclePropConfig> configsByPropIdCopy;
+ getConfigsByPropId([this, &configsByPropIdCopy](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ configsByPropIdCopy = configsByPropId;
+ });
{
std::scoped_lock<std::mutex> lockGuard(mLock);
dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
- dprintf(fd, "Containing %zu property configs\n", configsByPropId.size());
+ dprintf(fd, "Containing %zu property configs\n", configsByPropIdCopy.size());
dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index 8f7d19d..b59c92e 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.common",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/common/*.aidl"],
frozen: true,
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 78aefac..f3a3681 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.device",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/device/*.aidl"],
frozen: true,
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index ae8ba14..a9c1a1a 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.metadata",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/metadata/*.aidl"],
frozen: true,
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 38a8936..c055caa 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.provider",
+ host_supported: true,
vendor_available: true,
srcs: [
"android/hardware/camera/provider/*.aidl",
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 7157862..3b0a597 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -39,6 +39,7 @@
shared_libs: [
"libui",
"server_configurable_flags",
+ "libtracing_perfetto",
],
static_libs: [
"android.hardware.graphics.composer@2.1-vts",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index bda4198..431b1b6 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -55,6 +55,7 @@
"libui",
"android.hardware.common-V2-ndk",
"server_configurable_flags",
+ "libtracing_perfetto",
],
static_libs: [
"android.hardware.graphics.common@1.1",
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index 3464fe9..a2ab3d6 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -57,6 +57,7 @@
"libprocessgroup",
"libvndksupport",
"server_configurable_flags",
+ "libtracing_perfetto",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index bae362f..f398c53 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -719,6 +719,38 @@
}
/**
+ * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
+ */
+TEST_P(GraphicsMapperHidlTest, LockUnlockNoCPUUsage) {
+ const auto& info = mDummyDescriptorInfo;
+
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
+
+ // lock buffer with 0 usage
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+
+ hidl_handle acquireFenceHandle;
+
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ mGralloc->getMapper()->lock(buffer, 0, region, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& /*tmpData*/) {
+ EXPECT_EQ(Error::BAD_VALUE, tmpError)
+ << "Locking with 0 access succeeded";
+ });
+
+ mGralloc->getMapper()->unlock(buffer, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "Unlocking not locked buffer succeeded";
+ });
+
+ mGralloc->freeBuffer(bufferHandle);
+}
+
+/**
* Test multiple operations associated with different color formats
*/
TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index 1e0c427..bdbe4d0 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -750,6 +750,42 @@
}
/**
+ * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
+ */
+TEST_P(GraphicsMapperStableCTests, LockUnlockNoCPUUsage) {
+ constexpr auto usage = BufferUsage::CPU_READ_NEVER | BufferUsage::CPU_WRITE_NEVER;
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = usage,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const auto& info = buffer->info();
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE,
+ mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1,(void**)&data))
+ << "Locking with 0 access succeeded";
+
+ int releaseFence = -1;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER,
+ mapper()->v5.unlock(*handle, &releaseFence))
+ << "Unlocking not locked buffer succeeded";
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+/**
* Test multiple operations associated with different color formats
*/
TEST_P(GraphicsMapperStableCTests, Lock_YCRCB_420_SP) {
diff --git a/media/bufferpool/aidl/default/Accessor.cpp b/media/bufferpool/aidl/default/Accessor.cpp
index 423fd84..81e8eac 100644
--- a/media/bufferpool/aidl/default/Accessor.cpp
+++ b/media/bufferpool/aidl/default/Accessor.cpp
@@ -444,7 +444,7 @@
std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
std::mutex &mutex,
std::condition_variable &cv) {
- std::list<const std::weak_ptr<Accessor>> evictList;
+ std::list<std::weak_ptr<Accessor>> evictList;
while (true) {
int expired = 0;
int evicted = 0;
diff --git a/neuralnetworks/1.2/utils/test/DeviceTest.cpp b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
index 0d8c141..0e855c4 100644
--- a/neuralnetworks/1.2/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
@@ -54,6 +54,10 @@
.execTime = std::numeric_limits<float>::max(),
.powerUsage = std::numeric_limits<float>::max()};
+// FIXME: This function causes Clang to hang indefinitely when building with
+// -O1. Turn off optimization as a temporary workaround.
+// http://b/296850773
+#pragma clang optimize off
template <typename... Args>
auto makeCallbackReturn(Args&&... args) {
return [argPack = std::make_tuple(std::forward<Args>(args)...)](const auto& cb) {
@@ -61,6 +65,7 @@
return Void();
};
}
+#pragma clang optimize on
sp<MockDevice> createMockDevice() {
const auto mockDevice = MockDevice::create();
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index b214401..ec2a29c 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -2494,24 +2494,27 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- // Assert the value has changed
- serial = GetRandomSerialNumber();
- ndk::ScopedAStatus res = radio_network->isCellularIdentifierTransparencyEnabled(serial);
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ // Assert the value has changed
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->isCellularIdentifierTransparencyEnabled(serial);
- ASSERT_OK(res);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- EXPECT_EQ(valueToSet, radioRsp_network->isCellularIdentifierTransparencyEnabled);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ EXPECT_EQ(valueToSet, radioRsp_network->isCellularIdentifierTransparencyEnabled);
- // Reset original state
- radio_network->setCellularIdentifierTransparencyEnabled(serial, originalTransparencySetting);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ // Reset original state
+ radio_network->setCellularIdentifierTransparencyEnabled(serial,
+ originalTransparencySetting);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ }
}
/*
@@ -2547,24 +2550,26 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- // Assert the value has changed
- serial = GetRandomSerialNumber();
- ndk::ScopedAStatus res = radio_network->isSecurityAlgorithmsUpdatedEnabled(serial);
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ // Assert the value has changed
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->isSecurityAlgorithmsUpdatedEnabled(serial);
- ASSERT_OK(res);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- EXPECT_EQ(valueToSet, radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ EXPECT_EQ(valueToSet, radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
- // Reset original state
- radio_network->setSecurityAlgorithmsUpdatedEnabled(serial, originalSecuritySetting);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ // Reset original state
+ radio_network->setSecurityAlgorithmsUpdatedEnabled(serial, originalSecuritySetting);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ }
}
/**
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 06654c2..e9b68cc 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -118,7 +118,14 @@
EXPECT_EQ(CardStatus::STATE_PRESENT, slotStatus.cardState);
if (CardStatus::STATE_PRESENT == slotStatus.cardState) {
ASSERT_TRUE(slotStatus.portInfo[0].portActive);
- EXPECT_EQ(0, cardStatus.slotMap.portId);
+ if (cardStatus.supportedMepMode == aidl::android::hardware::radio::config::
+ MultipleEnabledProfilesMode::MEP_A1 ||
+ cardStatus.supportedMepMode == aidl::android::hardware::radio::config::
+ MultipleEnabledProfilesMode::MEP_A2) {
+ EXPECT_EQ(1, cardStatus.slotMap.portId);
+ } else {
+ EXPECT_EQ(0, cardStatus.slotMap.portId);
+ }
}
}
}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 5106561..464883e 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -39,7 +39,9 @@
class AttestKeyTest : public KeyMintAidlTestBase {
public:
void SetUp() override {
- skipAttestKeyTestIfNeeded();
+ if (shouldSkipAttestKeyTest()) {
+ GTEST_SKIP() << "Test using ATTEST_KEY is not applicable on waivered device";
+ }
KeyMintAidlTestBase::SetUp();
}
};
@@ -251,7 +253,11 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain);
- if (isRkpOnly() && result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
+ std::optional<bool> rkpOnly = isRkpOnly();
+ if (!rkpOnly.has_value()) {
+ GTEST_SKIP() << "Test not applicable because RKP-only status cannot be determined";
+ }
+ if (rkpOnly.value() && result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
GTEST_SKIP() << "RKP-only devices do not have a factory key";
}
ASSERT_EQ(ErrorCode::OK, result);
@@ -355,7 +361,8 @@
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
.SetDefaultValidity();
// In RKP-only systems, the first key cannot be attested due to lack of batch key
- if (!isRkpOnly() || i > 0) {
+ bool confirmedNotRkpOnly = !isRkpOnly().value_or(true);
+ if (confirmedNotRkpOnly || i > 0) {
auth_set_builder.AttestationChallenge("foo");
}
auto result = GenerateAttestKey(auth_set_builder, attest_key_opt, &key_blob_list[i],
@@ -363,7 +370,7 @@
ASSERT_EQ(ErrorCode::OK, result);
deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
- if (!isRkpOnly() || i > 0) {
+ if (confirmedNotRkpOnly || i > 0) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
@@ -386,7 +393,7 @@
}
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
- EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
+ EXPECT_GT(cert_chain_list[i].size(), i + (confirmedNotRkpOnly ? 1 : 0));
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
}
@@ -432,7 +439,8 @@
.Authorization(TAG_NO_AUTH_REQUIRED)
.SetDefaultValidity();
// In RKP-only systems, the first key cannot be attested due to lack of batch key
- if (!isRkpOnly() || i > 0) {
+ bool confirmedNotRkpOnly = !isRkpOnly().value_or(true);
+ if (confirmedNotRkpOnly || i > 0) {
auth_set_builder.AttestationChallenge("foo");
}
auto result = GenerateAttestKey(auth_set_builder, attest_key_opt, &key_blob_list[i],
@@ -440,7 +448,7 @@
ASSERT_EQ(ErrorCode::OK, result);
deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
- if (!isRkpOnly() || i > 0) {
+ if (confirmedNotRkpOnly || i > 0) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
@@ -459,7 +467,7 @@
}
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
- EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
+ EXPECT_GT(cert_chain_list[i].size(), i + (confirmedNotRkpOnly ? 1 : 0));
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
}
@@ -530,7 +538,8 @@
.Authorization(TAG_NO_AUTH_REQUIRED)
.SetDefaultValidity();
// In RKP-only systems, the first key cannot be attested due to lack of batch key
- if (!isRkpOnly() || i > 0) {
+ bool confirmedNotRkpOnly = !isRkpOnly().value_or(true);
+ if (confirmedNotRkpOnly || i > 0) {
auth_set_builder.AttestationChallenge("foo");
}
if ((i & 0x1) == 1) {
@@ -543,7 +552,7 @@
ASSERT_EQ(ErrorCode::OK, result);
deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
- if (!isRkpOnly() || i > 0) {
+ if (confirmedNotRkpOnly || i > 0) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
@@ -566,7 +575,7 @@
}
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
- EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
+ EXPECT_GT(cert_chain_list[i].size(), i + (confirmedNotRkpOnly ? 1 : 0));
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index cef8120..2ba75a3 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -250,7 +250,13 @@
return AidlVersion() >= 3 && property_get_int32("ro.vendor.api_level", 0) > __ANDROID_API_T__;
}
-bool KeyMintAidlTestBase::isRkpOnly() {
+std::optional<bool> KeyMintAidlTestBase::isRkpOnly() {
+ // GSI replaces the values for remote_prov_prop properties (since they’re system_internal_prop
+ // properties), so on GSI the properties are not reliable indicators of whether StrongBox/TEE is
+ // RKP-only or not.
+ if (is_gsi_image()) {
+ return std::nullopt;
+ }
if (SecLevel() == SecurityLevel::STRONGBOX) {
return property_get_bool("remote_provisioning.strongbox.rkp_only", false);
}
@@ -318,8 +324,11 @@
vector<Certificate> attest_cert_chain;
// If an attestation is requested, but the system is RKP-only, we need to supply an explicit
// attestation key. Else the result is a key without an attestation.
- if (isRkpOnly() && key_desc.Contains(TAG_ATTESTATION_CHALLENGE)) {
- skipAttestKeyTestIfNeeded();
+ // If the RKP-only value is undeterminable (i.e., when running on GSI), generate and use the
+ // attest key anyways. In the case that using an attest key is not supported
+ // (shouldSkipAttestKeyTest), assume the device has factory keys (so not RKP-only).
+ if (isRkpOnly().value_or(true) && key_desc.Contains(TAG_ATTESTATION_CHALLENGE) &&
+ !shouldSkipAttestKeyTest()) {
AuthorizationSet attest_key_desc =
AuthorizationSetBuilder().EcdsaKey(EcCurve::P_256).AttestKey().SetDefaultValidity();
attest_key.emplace();
@@ -1677,14 +1686,6 @@
is_attest_key_feature_disabled());
}
-// Skip a test that involves use of the ATTEST_KEY feature in specific configurations
-// where ATTEST_KEY is not supported (for either StrongBox or TEE).
-void KeyMintAidlTestBase::skipAttestKeyTestIfNeeded() const {
- if (shouldSkipAttestKeyTest()) {
- GTEST_SKIP() << "Test using ATTEST_KEY is not applicable on waivered device";
- }
-}
-
void verify_serial(X509* cert, const uint64_t expected_serial) {
BIGNUM_Ptr ser(BN_new());
EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 1bf2d9d..0368bba 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -104,7 +104,7 @@
uint32_t boot_patch_level();
bool isDeviceIdAttestationRequired();
bool isSecondImeiIdAttestationRequired();
- bool isRkpOnly();
+ std::optional<bool> isRkpOnly();
bool Curve25519Supported();
@@ -356,7 +356,6 @@
bool is_strongbox_enabled(void) const;
bool is_chipset_allowed_km4_strongbox(void) const;
bool shouldSkipAttestKeyTest(void) const;
- void skipAttestKeyTestIfNeeded() const;
void assert_mgf_digests_present_or_not_in_key_characteristics(
const vector<KeyCharacteristics>& key_characteristics,
diff --git a/security/keymint/support/fuzzer/Android.bp b/security/keymint/support/fuzzer/Android.bp
index 2fa82ec..a3ceb91 100644
--- a/security/keymint/support/fuzzer/Android.bp
+++ b/security/keymint/support/fuzzer/Android.bp
@@ -46,6 +46,21 @@
"hardware/interfaces/security/keymint/support/include",
"frameworks/native/libs/binder/ndk/include_platform",
],
+ fuzz_config: {
+ cc: [
+ "android-hardware-security@google.com",
+ ],
+ componentid: 1084733,
+ hotlists: [
+ "4593311",
+ "4271696",
+ ],
+ description: "The fuzzer targets the APIs of libkeymint_support",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
}
cc_defaults {
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
index 7a7c58b..9c306b5 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -60,7 +60,7 @@
ndk::SpAIBinder CustomVibrator::createBinder() {
auto binder = BnCustomVibrator::createBinder();
// e.g. AIBinder_setInheritRt(binder.get(), true);
- // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, 20);
+ // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, -2);
// e.g. AIBinder_setRequestingSid(binder.get(), true);
return binder;
}