diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2019-08-03 02:32:32 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-08-03 02:32:32 +0000 |
commit | 8813be6341051258bfb4c49642dc3300796b0e6c (patch) | |
tree | 1e724463f24e86eb5709b74d10e5009329307891 /sensors | |
parent | effdb89c974ffb24159e710e61a28f1fac167d35 (diff) | |
parent | 63d4f579762b8b1bba1d0e29c9959aaa838d4529 (diff) | |
download | android_hardware_interfaces-8813be6341051258bfb4c49642dc3300796b0e6c.tar.gz android_hardware_interfaces-8813be6341051258bfb4c49642dc3300796b0e6c.tar.bz2 android_hardware_interfaces-8813be6341051258bfb4c49642dc3300796b0e6c.zip |
Merge changes from topic "c2f2_sensors_vts" into qt-r1-dev
* changes:
Fix handling of reportToken when stopping
Change expected return type in direct report VTS
Add support for new gralloc HAL versions
Diffstat (limited to 'sensors')
-rw-r--r-- | sensors/1.0/vts/functional/Android.bp | 3 | ||||
-rw-r--r-- | sensors/2.0/vts/functional/Android.bp | 3 | ||||
-rw-r--r-- | sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp | 84 | ||||
-rw-r--r-- | sensors/common/vts/utils/Android.bp | 3 | ||||
-rw-r--r-- | sensors/common/vts/utils/GrallocWrapper.cpp | 362 | ||||
-rw-r--r-- | sensors/common/vts/utils/SensorsTestSharedMemory.cpp | 31 | ||||
-rw-r--r-- | sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h | 65 |
7 files changed, 303 insertions, 248 deletions
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp index 444797d4d..7bb992bf2 100644 --- a/sensors/1.0/vts/functional/Android.bp +++ b/sensors/1.0/vts/functional/Android.bp @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@2.1", + "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalSensorsTargetTestUtils", ], diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp index 98f0eacae..4765fa279 100644 --- a/sensors/2.0/vts/functional/Android.bp +++ b/sensors/2.0/vts/functional/Android.bp @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@2.1", + "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "android.hardware.sensors@2.0", "libfmq", diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp index 7f0c576f7..8364ba992 100644 --- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp +++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp @@ -182,14 +182,15 @@ class SensorsHidlTest : public SensorsHidlTestBase { int32_t getInvalidSensorHandle(); bool getDirectChannelSensor(SensorInfo* sensor, SharedMemType* memType, RateLevel* rate); void verifyDirectChannel(SharedMemType memType); - void verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType, - std::shared_ptr<SensorsTestSharedMemory> mem, - int32_t* directChannelHandle); + void verifyRegisterDirectChannel(std::shared_ptr<SensorsTestSharedMemory> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, + bool supportsAnyDirectChannel); void verifyConfigure(const SensorInfo& sensor, SharedMemType memType, - int32_t directChannelHandle); - void verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType, - int32_t directChannelHandle); + int32_t directChannelHandle, bool directChannelSupported); + void verifyUnregisterDirectChannel(int32_t directChannelHandle, bool directChannelSupported); void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, RateLevel rateLevel); + void queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType, + bool* supportsAnyDirectChannel); }; Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) { @@ -910,21 +911,43 @@ void SensorsHidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directCha [&](Result result, int32_t reportToken) { if (isDirectReportRateSupported(sensor, rateLevel)) { ASSERT_EQ(result, Result::OK); - ASSERT_GT(reportToken, 0); + if (rateLevel != RateLevel::STOP) { + ASSERT_GT(reportToken, 0); + } } else { ASSERT_EQ(result, Result::BAD_VALUE); } }); } -void SensorsHidlTest::verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType, - std::shared_ptr<SensorsTestSharedMemory> mem, - int32_t* directChannelHandle) { +void SensorsHidlTest::queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType, + bool* supportsAnyDirectChannel) { + *supportsSharedMemType = false; + *supportsAnyDirectChannel = false; + for (const SensorInfo& curSensor : getSensorsList()) { + if (isDirectChannelTypeSupported(curSensor, memType)) { + *supportsSharedMemType = true; + } + if (isDirectChannelTypeSupported(curSensor, SharedMemType::ASHMEM) || + isDirectChannelTypeSupported(curSensor, SharedMemType::GRALLOC)) { + *supportsAnyDirectChannel = true; + } + + if (*supportsSharedMemType && *supportsAnyDirectChannel) { + break; + } + } +} + +void SensorsHidlTest::verifyRegisterDirectChannel(std::shared_ptr<SensorsTestSharedMemory> mem, + int32_t* directChannelHandle, + bool supportsSharedMemType, + bool supportsAnyDirectChannel) { char* buffer = mem->getBuffer(); memset(buffer, 0xff, mem->getSize()); registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) { - if (isDirectChannelTypeSupported(sensor, memType)) { + if (supportsSharedMemType) { ASSERT_EQ(result, Result::OK); ASSERT_GT(channelHandle, 0); @@ -933,7 +956,9 @@ void SensorsHidlTest::verifyRegisterDirectChannel(const SensorInfo& sensor, Shar ASSERT_EQ(buffer[i], 0x00); } } else { - ASSERT_EQ(result, Result::INVALID_OPERATION); + Result expectedResult = + supportsAnyDirectChannel ? Result::BAD_VALUE : Result::INVALID_OPERATION; + ASSERT_EQ(result, expectedResult); ASSERT_EQ(channelHandle, -1); } *directChannelHandle = channelHandle; @@ -941,7 +966,7 @@ void SensorsHidlTest::verifyRegisterDirectChannel(const SensorInfo& sensor, Shar } void SensorsHidlTest::verifyConfigure(const SensorInfo& sensor, SharedMemType memType, - int32_t directChannelHandle) { + int32_t directChannelHandle, bool supportsAnyDirectChannel) { if (isDirectChannelTypeSupported(sensor, memType)) { // Verify that each rate level is properly supported checkRateLevel(sensor, directChannelHandle, RateLevel::NORMAL); @@ -957,22 +982,22 @@ void SensorsHidlTest::verifyConfigure(const SensorInfo& sensor, SharedMemType me -1 /* sensorHandle */, directChannelHandle, RateLevel::STOP, [](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::OK); }); } else { - // Direct channel is not supported for this SharedMemType + // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there + // is some level of direct channel report, otherwise return INVALID_OPERATION if direct + // channel is not supported at all + Result expectedResult = + supportsAnyDirectChannel ? Result::BAD_VALUE : Result::INVALID_OPERATION; configDirectReport(sensor.sensorHandle, directChannelHandle, RateLevel::NORMAL, - [](Result result, int32_t /* reportToken */) { - ASSERT_EQ(result, Result::INVALID_OPERATION); + [expectedResult](Result result, int32_t /* reportToken */) { + ASSERT_EQ(result, expectedResult); }); } } -void SensorsHidlTest::verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType, - int32_t directChannelHandle) { - Result result = unregisterDirectChannel(directChannelHandle); - if (isDirectChannelTypeSupported(sensor, memType)) { - ASSERT_EQ(result, Result::OK); - } else { - ASSERT_EQ(result, Result::INVALID_OPERATION); - } +void SensorsHidlTest::verifyUnregisterDirectChannel(int32_t directChannelHandle, + bool supportsAnyDirectChannel) { + Result expectedResult = supportsAnyDirectChannel ? Result::OK : Result::INVALID_OPERATION; + ASSERT_EQ(unregisterDirectChannel(directChannelHandle), expectedResult); } void SensorsHidlTest::verifyDirectChannel(SharedMemType memType) { @@ -983,11 +1008,16 @@ void SensorsHidlTest::verifyDirectChannel(SharedMemType memType) { SensorsTestSharedMemory::create(memType, kMemSize)); ASSERT_NE(mem, nullptr); + bool supportsSharedMemType; + bool supportsAnyDirectChannel; + queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel); + for (const SensorInfo& sensor : getSensorsList()) { int32_t directChannelHandle = 0; - verifyRegisterDirectChannel(sensor, memType, mem, &directChannelHandle); - verifyConfigure(sensor, memType, directChannelHandle); - verifyUnregisterDirectChannel(sensor, memType, directChannelHandle); + verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType, + supportsAnyDirectChannel); + verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel); + verifyUnregisterDirectChannel(directChannelHandle, supportsAnyDirectChannel); } } diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp index 8da554aa4..02dc60885 100644 --- a/sensors/common/vts/utils/Android.bp +++ b/sensors/common/vts/utils/Android.bp @@ -31,7 +31,10 @@ cc_library_static { ], static_libs: [ "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@2.1", + "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalHidlTargetTestBase", ], diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp index 222ef9611..1cad9135b 100644 --- a/sensors/common/vts/utils/GrallocWrapper.cpp +++ b/sensors/common/vts/utils/GrallocWrapper.cpp @@ -16,206 +16,262 @@ #include "GrallocWrapper.h" +#include <android/hardware/graphics/allocator/2.0/IAllocator.h> +#include <android/hardware/graphics/allocator/3.0/IAllocator.h> +#include <android/hardware/graphics/mapper/2.0/IMapper.h> +#include <android/hardware/graphics/mapper/2.1/IMapper.h> +#include <android/hardware/graphics/mapper/3.0/IMapper.h> + #include <utils/Log.h> +#include <cinttypes> +#include <type_traits> + +using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator; +using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator; +using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper; +using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; +using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper; + +using Error2 = ::android::hardware::graphics::mapper::V2_0::Error; +using Error3 = ::android::hardware::graphics::mapper::V3_0::Error; + +using ::android::hardware::graphics::common::V1_0::BufferUsage; +using ::android::hardware::graphics::common::V1_0::PixelFormat; + +// This is a typedef to the same underlying type across v2.0 and v3.0 +using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor; + +using ::android::hardware::hidl_handle; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; + namespace android { -GrallocWrapper::GrallocWrapper() { - init(); +// Since we use the same APIs across allocator/mapper HALs but they have major +// version differences (meaning they are not related through inheritance), we +// create a common interface abstraction for the IAllocator + IMapper combination +// (major versions need to match in the current HALs, e.g. IAllocator 3.0 needs to +// be paired with IMapper 3.0, so these are tied together) +class IGrallocHalWrapper { + public: + virtual ~IGrallocHalWrapper() = default; + + // IAllocator + virtual std::string dumpDebugInfo() = 0; + virtual native_handle_t* allocate(uint32_t size) = 0; + virtual void freeBuffer(native_handle_t* bufferHandle) = 0; + + // IMapper + virtual void* lock(native_handle_t* bufferHandle) = 0; + virtual void unlock(native_handle_t* bufferHandle) = 0; +}; + +namespace { + +bool failed(Error2 error) { + return (error != Error2::NONE); +} +bool failed(Error3 error) { + return (error != Error3::NONE); } -void GrallocWrapper::init() { - mAllocator = allocator2::IAllocator::getService(); - if (mAllocator == nullptr) { - ALOGE("Failed to get allocator service"); +// Since all the type and function names are the same for the things we use across the major HAL +// versions, we use template magic to avoid repeating ourselves. +template <typename AllocatorT, typename MapperT> +class GrallocHalWrapper : public IGrallocHalWrapper { + public: + GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper) + : mAllocator(allocator), mMapper(mapper) { + if (mapper->isRemote()) { + ALOGE("Mapper is in passthrough mode"); + } } - mMapper = mapper2::IMapper::getService(); - if (mMapper == nullptr) { - ALOGE("Failed to get mapper service"); - } else if (mMapper->isRemote()) { - ALOGE("Mapper is not in passthrough mode"); - } -} + virtual std::string dumpDebugInfo() override; + virtual native_handle_t* allocate(uint32_t size) override; + virtual void freeBuffer(native_handle_t* bufferHandle) override; -GrallocWrapper::~GrallocWrapper() { - for (auto bufferHandle : mClonedBuffers) { - auto buffer = const_cast<native_handle_t*>(bufferHandle); - native_handle_close(buffer); - native_handle_delete(buffer); - } - mClonedBuffers.clear(); + virtual void* lock(native_handle_t* bufferHandle) override; + virtual void unlock(native_handle_t* bufferHandle) override; - for (auto bufferHandle : mImportedBuffers) { - auto buffer = const_cast<native_handle_t*>(bufferHandle); - if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) { - ALOGE("Failed to free buffer %p", buffer); - } - } - mImportedBuffers.clear(); -} + private: + static constexpr uint64_t kBufferUsage = + static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN); + sp<AllocatorT> mAllocator; + sp<MapperT> mMapper; -sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const { - return mAllocator; -} + BufferDescriptor getDescriptor(uint32_t size); + native_handle_t* importBuffer(const hidl_handle& rawHandle); +}; -std::string GrallocWrapper::dumpDebugInfo() { +template <typename AllocatorT, typename MapperT> +std::string GrallocHalWrapper<AllocatorT, MapperT>::dumpDebugInfo() { std::string debugInfo; - mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); - + mAllocator->dumpDebugInfo([&](const hidl_string& tmpDebugInfo) { debugInfo = tmpDebugInfo; }); return debugInfo; } -const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) { - const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); +template <typename AllocatorT, typename MapperT> +native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) { + constexpr uint32_t kBufferCount = 1; + BufferDescriptor descriptor = getDescriptor(size); + native_handle_t* bufferHandle = nullptr; + + auto callback = [&](auto error, uint32_t /*stride*/, const hidl_vec<hidl_handle>& buffers) { + if (failed(error)) { + ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error)); + } else if (buffers.size() != kBufferCount) { + ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", buffers.size(), + kBufferCount); + } else { + bufferHandle = importBuffer(buffers[0]); + } + }; - if (bufferHandle) { - mClonedBuffers.insert(bufferHandle); - } + mAllocator->allocate(descriptor, kBufferCount, callback); return bufferHandle; } -std::vector<const native_handle_t*> GrallocWrapper::allocate( - const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, uint32_t* outStride) { - std::vector<const native_handle_t*> bufferHandles; - bufferHandles.reserve(count); - mAllocator->allocate(descriptor, count, - [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { - if (mapper2::Error::NONE != tmpError) { - ALOGE("Failed to allocate buffers"); - } - if (count != tmpBuffers.size()) { - ALOGE("Invalid buffer array"); - } - - for (uint32_t i = 0; i < count; i++) { - if (import) { - bufferHandles.push_back(importBuffer(tmpBuffers[i])); - } else { - bufferHandles.push_back(cloneBuffer(tmpBuffers[i])); - } - } - - if (outStride) { - *outStride = tmpStride; - } - }); - - return bufferHandles; -} - -const native_handle_t* GrallocWrapper::allocate( - const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import, - uint32_t* outStride) { - mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo); - auto buffers = allocate(descriptor, 1, import, outStride); - return buffers[0]; -} - -sp<mapper2::IMapper> GrallocWrapper::getMapper() const { - return mMapper; +template <typename AllocatorT, typename MapperT> +void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) { + auto error = mMapper->freeBuffer(bufferHandle); + if (!error.isOk() || failed(error)) { + ALOGE("Failed to free buffer %p", bufferHandle); + } } -mapper2::BufferDescriptor GrallocWrapper::createDescriptor( - const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) { - mapper2::BufferDescriptor descriptor; - mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { - if (tmpError != mapper2::Error::NONE) { - ALOGE("Failed to create descriptor"); +template <typename AllocatorT, typename MapperT> +BufferDescriptor GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) { + typename MapperT::BufferDescriptorInfo descriptorInfo = { + .width = size, + .height = 1, + .layerCount = 1, + .usage = kBufferUsage, + .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB), + }; + + BufferDescriptor descriptor; + auto callback = [&](auto error, const BufferDescriptor& tmpDescriptor) { + if (failed(error)) { + ALOGE("Failed to create descriptor: %" PRId32, static_cast<int32_t>(error)); + } else { + descriptor = tmpDescriptor; } - descriptor = tmpDescriptor; - }); + }; + mMapper->createDescriptor(descriptorInfo, callback); return descriptor; } -const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) { - const native_handle_t* bufferHandle = nullptr; - mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { - if (tmpError != mapper2::Error::NONE) { - ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle()); +template <typename AllocatorT, typename MapperT> +native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer( + const hidl_handle& rawHandle) { + native_handle_t* bufferHandle = nullptr; + + mMapper->importBuffer(rawHandle, [&](auto error, void* tmpBuffer) { + if (failed(error)) { + ALOGE("Failed to import buffer %p: %" PRId32, rawHandle.getNativeHandle(), + static_cast<int32_t>(error)); + } else { + bufferHandle = static_cast<native_handle_t*>(tmpBuffer); } - bufferHandle = static_cast<const native_handle_t*>(tmpBuffer); }); - if (bufferHandle) { - mImportedBuffers.insert(bufferHandle); - } - return bufferHandle; } -void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) { - auto buffer = const_cast<native_handle_t*>(bufferHandle); +template <typename AllocatorT, typename MapperT> +void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) { + // Per the HAL, all-zeros Rect means the entire buffer + typename MapperT::Rect accessRegion = {}; + hidl_handle acquireFenceHandle; // No fence needed, already safe to lock - if (mImportedBuffers.erase(bufferHandle)) { - mapper2::Error error = mMapper->freeBuffer(buffer); - if (error != mapper2::Error::NONE) { - ALOGE("Failed to free %p", buffer); + void* data = nullptr; + mMapper->lock(bufferHandle, kBufferUsage, accessRegion, acquireFenceHandle, + [&](auto error, void* tmpData, ...) { // V3_0 passes extra args we don't use + if (failed(error)) { + ALOGE("Failed to lock buffer %p: %" PRId32, bufferHandle, + static_cast<int32_t>(error)); + } else { + data = tmpData; + } + }); + + return data; +} + +template <typename AllocatorT, typename MapperT> +void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) { + mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) { + if (failed(error)) { + ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle, + static_cast<int32_t>(error)); } - } else { - mClonedBuffers.erase(bufferHandle); - native_handle_close(buffer); - native_handle_delete(buffer); - } + }); } -void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, - const mapper2::IMapper::Rect& accessRegion, int acquireFence) { - auto buffer = const_cast<native_handle_t*>(bufferHandle); +} // anonymous namespace - NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); - hardware::hidl_handle acquireFenceHandle; - if (acquireFence >= 0) { - auto h = native_handle_init(acquireFenceStorage, 1, 0); - h->data[0] = acquireFence; - acquireFenceHandle = h; - } +GrallocWrapper::GrallocWrapper() { + sp<IAllocator3> allocator3 = IAllocator3::getService(); + sp<IMapper3> mapper3 = IMapper3::getService(); - void* data = nullptr; - mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle, - [&](const auto& tmpError, const auto& tmpData) { - if (tmpError != mapper2::Error::NONE) { - ALOGE("Failed to lock buffer %p", buffer); - } - data = tmpData; - }); + if (allocator3 != nullptr && mapper3 != nullptr) { + mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( + new GrallocHalWrapper<IAllocator3, IMapper3>(allocator3, mapper3)); + } else { + ALOGD("Graphics HALs 3.0 not found (allocator %d mapper %d), falling back to 2.x", + (allocator3 != nullptr), (mapper3 != nullptr)); - if (acquireFence >= 0) { - close(acquireFence); - } + sp<IAllocator2> allocator2 = IAllocator2::getService(); + sp<IMapper2> mapper2 = IMapper2_1::getService(); + if (mapper2 == nullptr) { + mapper2 = IMapper2::getService(); + } - return data; + if (allocator2 != nullptr && mapper2 != nullptr) { + mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( + new GrallocHalWrapper<IAllocator2, IMapper2>(allocator2, mapper2)); + } else { + ALOGE("Couldn't open 2.x/3.0 graphics HALs (2.x allocator %d mapper %d)", + (allocator2 != nullptr), (mapper2 != nullptr)); + } + } } -int GrallocWrapper::unlock(const native_handle_t* bufferHandle) { - auto buffer = const_cast<native_handle_t*>(bufferHandle); +GrallocWrapper::~GrallocWrapper() { + for (auto bufferHandle : mAllocatedBuffers) { + mGrallocHal->unlock(bufferHandle); + mGrallocHal->freeBuffer(bufferHandle); + } + mAllocatedBuffers.clear(); +} - int releaseFence = -1; - mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { - if (tmpError != mapper2::Error::NONE) { - ALOGE("Failed to unlock buffer %p", buffer); - } +std::string GrallocWrapper::dumpDebugInfo() { + return mGrallocHal->dumpDebugInfo(); +} - auto fenceHandle = tmpReleaseFence.getNativeHandle(); - if (fenceHandle) { - if (fenceHandle->numInts != 0) { - ALOGE("Invalid fence handle %p", fenceHandle); - } - if (fenceHandle->numFds == 1) { - releaseFence = dup(fenceHandle->data[0]); - if (releaseFence < 0) { - ALOGE("Failed to dup fence fd"); - } - } else { - if (fenceHandle->numFds != 0) { - ALOGE("Invalid fence handle %p", fenceHandle); - } - } +std::pair<native_handle_t*, void*> GrallocWrapper::allocate(uint32_t size) { + native_handle_t* bufferHandle = mGrallocHal->allocate(size); + void* buffer = nullptr; + if (bufferHandle) { + buffer = mGrallocHal->lock(bufferHandle); + if (buffer) { + mAllocatedBuffers.insert(bufferHandle); + } else { + mGrallocHal->freeBuffer(bufferHandle); + bufferHandle = nullptr; } - }); + } + return std::make_pair<>(bufferHandle, buffer); +} - return releaseFence; +void GrallocWrapper::freeBuffer(native_handle_t* bufferHandle) { + if (mAllocatedBuffers.erase(bufferHandle)) { + mGrallocHal->unlock(bufferHandle); + mGrallocHal->freeBuffer(bufferHandle); + } } } // namespace android diff --git a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp index 819e2974f..3b068bd5c 100644 --- a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp +++ b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp @@ -119,32 +119,13 @@ SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size } case SharedMemType::GRALLOC: { mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); - if (mGrallocWrapper->getAllocator() == nullptr || - mGrallocWrapper->getMapper() == nullptr) { + if (!mGrallocWrapper->isInitialized()) { break; } - using android::hardware::graphics::common::V1_0::BufferUsage; - using android::hardware::graphics::common::V1_0::PixelFormat; - mapper2::IMapper::BufferDescriptorInfo buf_desc_info = { - .width = static_cast<uint32_t>(size), - .height = 1, - .layerCount = 1, - .usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | - BufferUsage::CPU_READ_OFTEN), - .format = PixelFormat::BLOB}; - - handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info)); - if (handle != nullptr) { - mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width), - static_cast<int32_t>(buf_desc_info.height)}; - buffer = static_cast<char*>( - mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1)); - if (buffer != nullptr) { - break; - } - mGrallocWrapper->freeBuffer(handle); - handle = nullptr; - } + + std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); + handle = buf.first; + buffer = static_cast<char*>(buf.second); break; } default: @@ -175,9 +156,7 @@ SensorsTestSharedMemory::~SensorsTestSharedMemory() { } case SharedMemType::GRALLOC: { if (mSize != 0) { - mGrallocWrapper->unlock(mNativeHandle); mGrallocWrapper->freeBuffer(mNativeHandle); - mNativeHandle = nullptr; mSize = 0; } diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h index 3bd73c36e..41e633489 100644 --- a/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h +++ b/sensors/common/vts/utils/include/sensors-vts-utils/GrallocWrapper.h @@ -14,66 +14,47 @@ * limitations under the License. */ -#ifndef GRALLO_WRAPPER_H_ -#define GRALLO_WRAPPER_H_ +#pragma once -#include <unordered_set> - -#include <android/hardware/graphics/allocator/2.0/IAllocator.h> -#include <android/hardware/graphics/mapper/2.0/IMapper.h> +#include <utils/NativeHandle.h> -namespace allocator2 = ::android::hardware::graphics::allocator::V2_0; -namespace mapper2 = ::android::hardware::graphics::mapper::V2_0; +#include <memory> +#include <string> +#include <unordered_set> +#include <utility> namespace android { -// Modified from hardware/interfaces/graphics/mapper/2.0/vts/functional/ +class IGrallocHalWrapper; + +// Reference: hardware/interfaces/graphics/mapper/2.0/vts/functional/ class GrallocWrapper { public: GrallocWrapper(); ~GrallocWrapper(); - sp<allocator2::IAllocator> getAllocator() const; - sp<mapper2::IMapper> getMapper() const; + // After constructing this object, this function must be called to check the result. If it + // returns false, other methods are not safe to call. + bool isInitialized() const { return (mGrallocHal != nullptr); }; std::string dumpDebugInfo(); - // When import is false, this simply calls IAllocator::allocate. When import - // is true, the returned buffers are also imported into the mapper. - // - // Either case, the returned buffers must be freed with freeBuffer. - std::vector<const native_handle_t*> allocate(const mapper2::BufferDescriptor& descriptor, - uint32_t count, bool import = true, - uint32_t* outStride = nullptr); - const native_handle_t* allocate(const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, - bool import = true, uint32_t* outStride = nullptr); - - mapper2::BufferDescriptor createDescriptor( - const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo); - - const native_handle_t* importBuffer(const hardware::hidl_handle& rawHandle); - void freeBuffer(const native_handle_t* bufferHandle); - - // We use fd instead of hardware::hidl_handle in these functions to pass fences - // in and out of the mapper. The ownership of the fd is always transferred - // with each of these functions. - void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, - const mapper2::IMapper::Rect& accessRegion, int acquireFence); - - int unlock(const native_handle_t* bufferHandle); + // Allocates a gralloc buffer suitable for direct channel sensors usage with the given size. + // The buffer should be freed using freeBuffer when it's not needed anymore; otherwise it'll + // be freed when this object is destroyed. + // Returns a handle to the buffer, and a CPU-accessible pointer for reading. On failure, both + // will be set to nullptr. + std::pair<native_handle_t*, void*> allocate(uint32_t size); - private: - void init(); - const native_handle_t* cloneBuffer(const hardware::hidl_handle& rawHandle); + // Releases a gralloc buffer previously returned by allocate() + void freeBuffer(native_handle_t* bufferHandle); - sp<allocator2::IAllocator> mAllocator; - sp<mapper2::IMapper> mMapper; + private: + std::unique_ptr<IGrallocHalWrapper> mGrallocHal; // Keep track of all cloned and imported handles. When a test fails with // ASSERT_*, the destructor will free the handles for the test. - std::unordered_set<const native_handle_t*> mClonedBuffers; - std::unordered_set<const native_handle_t*> mImportedBuffers; + std::unordered_set<native_handle_t*> mAllocatedBuffers; }; } // namespace android -#endif // GRALLO_WRAPPER_H_ |