Merge "Check API values only if modem supports APIs" into main
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/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/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/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;
}