1 /* 2 * Copyright (C) 2022 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_AIDL_TEST_SHARED_MEMORY_H 18 #define ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H 19 20 #include "sensors-vts-utils/GrallocWrapper.h" 21 22 #include <aidlcommonsupport/NativeHandle.h> 23 #include <android-base/macros.h> 24 #include <log/log.h> 25 26 #include <sys/mman.h> 27 #include <cinttypes> 28 29 #include <cutils/ashmem.h> 30 31 using ::aidl::android::hardware::sensors::BnSensors; 32 using ::aidl::android::hardware::sensors::Event; 33 using ::aidl::android::hardware::sensors::ISensors; 34 using ::aidl::android::hardware::sensors::SensorType; 35 36 template <class SensorType, class Event> 37 class SensorsAidlTestSharedMemory { 38 public: create(ISensors::SharedMemInfo::SharedMemType type,size_t size)39 static SensorsAidlTestSharedMemory* create(ISensors::SharedMemInfo::SharedMemType type, 40 size_t size) { 41 constexpr size_t kMaxSize = 42 128 * 1024 * 1024; // sensor test should not need more than 128M 43 if (size == 0 || size >= kMaxSize) { 44 return nullptr; 45 } 46 47 auto m = new SensorsAidlTestSharedMemory<SensorType, Event>(type, size); 48 if (m->mSize != size || m->mBuffer == nullptr) { 49 delete m; 50 m = nullptr; 51 } 52 return m; 53 } 54 getSharedMemInfo()55 ISensors::SharedMemInfo getSharedMemInfo() const { 56 ISensors::SharedMemInfo mem = { 57 .type = mType, 58 .format = ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT, 59 .size = static_cast<int32_t>(mSize), 60 .memoryHandle = android::dupToAidl(mNativeHandle)}; 61 return mem; 62 } getBuffer()63 char* getBuffer() const { return mBuffer; } getSize()64 size_t getSize() const { return mSize; } 65 std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const { 66 constexpr size_t kEventSize = 67 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); 68 constexpr size_t kOffsetSize = 69 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD); 70 constexpr size_t kOffsetToken = 71 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN); 72 constexpr size_t kOffsetType = 73 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE); 74 constexpr size_t kOffsetAtomicCounter = static_cast<size_t>( 75 BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER); 76 constexpr size_t kOffsetTimestamp = 77 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP); 78 constexpr size_t kOffsetData = 79 static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA); 80 81 std::vector<Event> events; 82 std::vector<float> data(16); 83 84 while (offset + kEventSize <= mSize) { 85 int64_t atomicCounter = 86 *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter); 87 if (atomicCounter <= lastCounter) { 88 ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, 89 lastCounter); 90 break; 91 } 92 93 int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize); 94 if (size != kEventSize) { 95 // unknown error, events parsed may be wrong, remove all 96 events.clear(); 97 break; 98 } 99 100 int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken); 101 int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType); 102 int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp); 103 104 ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 105 ", timestamp %" PRId64, 106 offset, atomicCounter, token, type, timestamp); 107 108 Event event = { 109 .timestamp = timestamp, 110 .sensorHandle = token, 111 .sensorType = type, 112 }; 113 114 event.set<Event::Data>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); 115 // event.u.data = android::hardware::hidl_array<float, 116 // 16>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); 117 118 events.push_back(event); 119 120 lastCounter = atomicCounter; 121 offset += kEventSize; 122 } 123 124 return events; 125 } 126 ~SensorsAidlTestSharedMemory()127 virtual ~SensorsAidlTestSharedMemory() { 128 switch (mType) { 129 case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { 130 if (mSize != 0) { 131 ::munmap(mBuffer, mSize); 132 mBuffer = nullptr; 133 134 ::native_handle_close(mNativeHandle); 135 ::native_handle_delete(mNativeHandle); 136 137 mNativeHandle = nullptr; 138 mSize = 0; 139 } 140 break; 141 } 142 case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { 143 if (mSize != 0) { 144 mGrallocWrapper->freeBuffer(mNativeHandle); 145 mNativeHandle = nullptr; 146 mSize = 0; 147 } 148 break; 149 } 150 default: { 151 if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) { 152 ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: " 153 "type %d, native handle %p, size %zu, buffer %p", 154 this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer); 155 } 156 break; 157 } 158 } 159 } 160 161 private: SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type,size_t size)162 SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type, size_t size) 163 : mType(type), mSize(0), mBuffer(nullptr) { 164 native_handle_t* handle = nullptr; 165 char* buffer = nullptr; 166 switch (type) { 167 case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { 168 int fd; 169 handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); 170 if (handle != nullptr) { 171 handle->data[0] = fd = 172 ::ashmem_create_region("SensorsAidlTestSharedMemory", size); 173 if (handle->data[0] > 0) { 174 // memory is pinned by default 175 buffer = static_cast<char*>( 176 ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); 177 if (buffer != reinterpret_cast<char*>(MAP_FAILED)) { 178 break; 179 } 180 ::native_handle_close(handle); 181 } 182 ::native_handle_delete(handle); 183 handle = nullptr; 184 } 185 break; 186 } 187 case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { 188 mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); 189 if (!mGrallocWrapper->isInitialized()) { 190 break; 191 } 192 193 std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); 194 handle = buf.first; 195 buffer = static_cast<char*>(buf.second); 196 break; 197 } 198 default: 199 break; 200 } 201 202 if (buffer != nullptr) { 203 mNativeHandle = handle; 204 mSize = size; 205 mBuffer = buffer; 206 } 207 } 208 209 ISensors::SharedMemInfo::SharedMemType mType; 210 native_handle_t* mNativeHandle; 211 size_t mSize; 212 char* mBuffer; 213 std::unique_ptr<::android::GrallocWrapper> mGrallocWrapper; 214 215 DISALLOW_COPY_AND_ASSIGN(SensorsAidlTestSharedMemory); 216 }; 217 218 #endif // ANDROID_SENSORS_TEST_SHARED_MEMORY_H 219