1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_SENSORS_TEST_SHARED_MEMORY_H 18 #define ANDROID_SENSORS_TEST_SHARED_MEMORY_H 19 20 #include <aidl/android/hardware/graphics/common/BufferUsage.h> 21 #include <aidl/android/hardware/graphics/common/PixelFormat.h> 22 #include <ui/GraphicBuffer.h> 23 #include <ui/GraphicBufferAllocator.h> 24 #include <ui/GraphicBufferMapper.h> 25 26 #include <android-base/macros.h> 27 #include <log/log.h> 28 29 #include <sys/mman.h> 30 #include <cinttypes> 31 32 #include <cutils/ashmem.h> 33 34 using namespace ::android::hardware::sensors::V1_0; 35 using ::aidl::android::hardware::graphics::common::BufferUsage; 36 using ::aidl::android::hardware::graphics::common::PixelFormat; 37 38 template <class SensorTypeVersion, class EventType> 39 class SensorsTestSharedMemory { 40 public: create(SharedMemType type,size_t size)41 static SensorsTestSharedMemory* create(SharedMemType type, size_t size) { 42 constexpr size_t kMaxSize = 43 128 * 1024 * 1024; // sensor test should not need more than 128M 44 if (size == 0 || size >= kMaxSize) { 45 return nullptr; 46 } 47 48 auto m = new SensorsTestSharedMemory<SensorTypeVersion, EventType>(type, size); 49 if (m->mSize != size || m->mBuffer == nullptr) { 50 delete m; 51 m = nullptr; 52 } 53 return m; 54 } 55 getSharedMemInfo()56 SharedMemInfo getSharedMemInfo() const { 57 if (mType == SharedMemType::GRALLOC) { 58 SharedMemInfo mem = {.type = mType, 59 .format = SharedMemFormat::SENSORS_EVENT, 60 .size = static_cast<uint32_t>(mSize), 61 .memoryHandle = mBufferHandle}; 62 return mem; 63 64 } else { 65 SharedMemInfo mem = {.type = mType, 66 .format = SharedMemFormat::SENSORS_EVENT, 67 .size = static_cast<uint32_t>(mSize), 68 .memoryHandle = mNativeHandle}; 69 return mem; 70 } 71 } getBuffer()72 char* getBuffer() const { return mBuffer; } getSize()73 size_t getSize() const { return mSize; } 74 std::vector<EventType> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const { 75 constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH); 76 constexpr size_t kOffsetSize = static_cast<size_t>(SensorsEventFormatOffset::SIZE_FIELD); 77 constexpr size_t kOffsetToken = static_cast<size_t>(SensorsEventFormatOffset::REPORT_TOKEN); 78 constexpr size_t kOffsetType = static_cast<size_t>(SensorsEventFormatOffset::SENSOR_TYPE); 79 constexpr size_t kOffsetAtomicCounter = 80 static_cast<size_t>(SensorsEventFormatOffset::ATOMIC_COUNTER); 81 constexpr size_t kOffsetTimestamp = 82 static_cast<size_t>(SensorsEventFormatOffset::TIMESTAMP); 83 constexpr size_t kOffsetData = static_cast<size_t>(SensorsEventFormatOffset::DATA); 84 85 std::vector<EventType> events; 86 std::vector<float> data(16); 87 88 while (offset + kEventSize <= mSize) { 89 int64_t atomicCounter = 90 *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter); 91 if (atomicCounter <= lastCounter) { 92 ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, 93 lastCounter); 94 break; 95 } 96 97 int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize); 98 if (size != kEventSize) { 99 // unknown error, events parsed may be wrong, remove all 100 events.clear(); 101 break; 102 } 103 104 int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken); 105 int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType); 106 int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp); 107 108 ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 109 ", timestamp %" PRId64, 110 offset, atomicCounter, token, type, timestamp); 111 112 EventType event = { 113 .timestamp = timestamp, 114 .sensorHandle = token, 115 .sensorType = static_cast<SensorTypeVersion>(type), 116 }; 117 event.u.data = android::hardware::hidl_array<float, 16>( 118 reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); 119 120 events.push_back(event); 121 122 lastCounter = atomicCounter; 123 offset += kEventSize; 124 } 125 126 return events; 127 } 128 ~SensorsTestSharedMemory()129 virtual ~SensorsTestSharedMemory() { 130 switch (mType) { 131 case SharedMemType::ASHMEM: { 132 if (mSize != 0) { 133 ::munmap(mBuffer, mSize); 134 mBuffer = nullptr; 135 136 ::native_handle_close(mNativeHandle); 137 ::native_handle_delete(mNativeHandle); 138 139 mNativeHandle = nullptr; 140 mSize = 0; 141 } 142 break; 143 } 144 case SharedMemType::GRALLOC: { 145 if (mSize != 0) { 146 android::status_t status = 147 android::GraphicBufferAllocator::get().free(mBufferHandle); 148 if (status != android::OK) { 149 ALOGE("SensorsAidlTestSharedMemory Gralloc failed to free buffer. Status: " 150 "%s", 151 android::statusToString(status).c_str()); 152 } 153 mBufferHandle = nullptr; 154 mBuffer = nullptr; 155 mSize = 0; 156 } 157 break; 158 } 159 default: { 160 if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr || 161 mBufferHandle != nullptr) { 162 ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: " 163 "type %d, native handle %p, size %zu, buffer %p, buffer handle %p", 164 this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer, 165 mBufferHandle); 166 } 167 break; 168 } 169 } 170 } 171 172 private: SensorsTestSharedMemory(SharedMemType type,size_t size)173 SensorsTestSharedMemory(SharedMemType type, size_t size) 174 : mType(type), mSize(0), mBuffer(nullptr) { 175 native_handle_t* handle = nullptr; 176 char* buffer = nullptr; 177 switch (type) { 178 case SharedMemType::ASHMEM: { 179 int fd; 180 handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); 181 if (handle != nullptr) { 182 handle->data[0] = fd = ::ashmem_create_region("SensorsTestSharedMemory", size); 183 if (handle->data[0] > 0) { 184 // memory is pinned by default 185 buffer = static_cast<char*>( 186 ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); 187 if (buffer != reinterpret_cast<char*>(MAP_FAILED)) { 188 break; 189 } 190 ::native_handle_close(handle); 191 } 192 ::native_handle_delete(handle); 193 handle = nullptr; 194 } 195 break; 196 } 197 case SharedMemType::GRALLOC: { 198 static constexpr uint64_t kBufferUsage = 199 static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA) | 200 static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) | 201 static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY); 202 203 uint32_t stride = 0; 204 buffer_handle_t bufferHandle; 205 android::status_t status = android::GraphicBufferAllocator::get().allocate( 206 size, 1, static_cast<int>(PixelFormat::BLOB), 1, kBufferUsage, 207 &bufferHandle, &stride, "SensorVts"); 208 if (status != android::OK) { 209 ALOGE("SensorsAidlTestSharedMemory failed to allocate memory. Status: %s", 210 android::statusToString(status).c_str()); 211 break; 212 } 213 // Per the HAL, all-zeros Rect means the entire buffer 214 android::Rect rect = {0, 0, 0, 0}; 215 void* ret; 216 status = android::GraphicBufferMapper::get().lock(bufferHandle, kBufferUsage, rect, 217 &ret); 218 if (status != android::OK) { 219 ALOGE("SensorsAidlTestSharedMemory failed to import buffer: Status: %s", 220 android::statusToString(status).c_str()); 221 } else { 222 buffer = static_cast<char*>(ret); 223 mBufferHandle = bufferHandle; 224 } 225 break; 226 } 227 default: 228 break; 229 } 230 231 if (buffer != nullptr) { 232 mNativeHandle = handle; 233 mSize = size; 234 mBuffer = buffer; 235 } 236 } 237 238 SharedMemType mType; 239 native_handle_t* mNativeHandle; 240 buffer_handle_t mBufferHandle; 241 size_t mSize; 242 char* mBuffer; 243 244 DISALLOW_COPY_AND_ASSIGN(SensorsTestSharedMemory); 245 }; 246 247 #endif // ANDROID_SENSORS_TEST_SHARED_MEMORY_H 248