diff options
Diffstat (limited to 'sensors/common/vts/utils/SensorsTestSharedMemory.cpp')
| -rw-r--r-- | sensors/common/vts/utils/SensorsTestSharedMemory.cpp | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp new file mode 100644 index 0000000000..819e2974f7 --- /dev/null +++ b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SensorsTestSharedMemory.h" + +#include <log/log.h> + +#include <sys/mman.h> +#include <cinttypes> + +using namespace ::android::hardware::sensors::V1_0; + +SharedMemInfo SensorsTestSharedMemory::getSharedMemInfo() const { + SharedMemInfo mem = {.type = mType, + .format = SharedMemFormat::SENSORS_EVENT, + .size = static_cast<uint32_t>(mSize), + .memoryHandle = mNativeHandle}; + return mem; +} + +char* SensorsTestSharedMemory::getBuffer() const { + return mBuffer; +} + +size_t SensorsTestSharedMemory::getSize() const { + return mSize; +} + +std::vector<Event> SensorsTestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const { + constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH); + constexpr size_t kOffsetSize = static_cast<size_t>(SensorsEventFormatOffset::SIZE_FIELD); + constexpr size_t kOffsetToken = static_cast<size_t>(SensorsEventFormatOffset::REPORT_TOKEN); + constexpr size_t kOffsetType = static_cast<size_t>(SensorsEventFormatOffset::SENSOR_TYPE); + constexpr size_t kOffsetAtomicCounter = + static_cast<size_t>(SensorsEventFormatOffset::ATOMIC_COUNTER); + constexpr size_t kOffsetTimestamp = static_cast<size_t>(SensorsEventFormatOffset::TIMESTAMP); + constexpr size_t kOffsetData = static_cast<size_t>(SensorsEventFormatOffset::DATA); + + std::vector<Event> events; + std::vector<float> data(16); + + while (offset + kEventSize <= mSize) { + int64_t atomicCounter = + *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter); + if (atomicCounter <= lastCounter) { + ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, + lastCounter); + break; + } + + int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize); + if (size != kEventSize) { + // unknown error, events parsed may be wrong, remove all + events.clear(); + break; + } + + int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken); + int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType); + int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp); + + ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 + ", timestamp %" PRId64, + offset, atomicCounter, token, type, timestamp); + + Event event = { + .timestamp = timestamp, + .sensorHandle = token, + .sensorType = static_cast<SensorType>(type), + }; + event.u.data = android::hardware::hidl_array<float, 16>( + reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); + + events.push_back(event); + + lastCounter = atomicCounter; + offset += kEventSize; + } + + return events; +} + +SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size) + : mType(type), mSize(0), mBuffer(nullptr) { + native_handle_t* handle = nullptr; + char* buffer = nullptr; + switch (type) { + case SharedMemType::ASHMEM: { + int fd; + handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); + if (handle != nullptr) { + handle->data[0] = fd = ::ashmem_create_region("SensorsTestSharedMemory", size); + if (handle->data[0] > 0) { + // memory is pinned by default + buffer = static_cast<char*>( + ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + if (buffer != reinterpret_cast<char*>(MAP_FAILED)) { + break; + } + ::native_handle_close(handle); + } + ::native_handle_delete(handle); + handle = nullptr; + } + break; + } + case SharedMemType::GRALLOC: { + mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); + if (mGrallocWrapper->getAllocator() == nullptr || + mGrallocWrapper->getMapper() == nullptr) { + 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; + } + break; + } + default: + break; + } + + if (buffer != nullptr) { + mNativeHandle = handle; + mSize = size; + mBuffer = buffer; + } +} + +SensorsTestSharedMemory::~SensorsTestSharedMemory() { + switch (mType) { + case SharedMemType::ASHMEM: { + if (mSize != 0) { + ::munmap(mBuffer, mSize); + mBuffer = nullptr; + + ::native_handle_close(mNativeHandle); + ::native_handle_delete(mNativeHandle); + + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + case SharedMemType::GRALLOC: { + if (mSize != 0) { + mGrallocWrapper->unlock(mNativeHandle); + mGrallocWrapper->freeBuffer(mNativeHandle); + + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + default: { + if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) { + ALOGE( + "SensorsTestSharedMemory %p not properly destructed: " + "type %d, native handle %p, size %zu, buffer %p", + this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer); + } + break; + } + } +} + +SensorsTestSharedMemory* SensorsTestSharedMemory::create(SharedMemType type, size_t size) { + constexpr size_t kMaxSize = 128 * 1024 * 1024; // sensor test should not need more than 128M + if (size == 0 || size >= kMaxSize) { + return nullptr; + } + + auto m = new SensorsTestSharedMemory(type, size); + if (m->mSize != size || m->mBuffer == nullptr) { + delete m; + m = nullptr; + } + return m; +} |
