1 /* 2 * Copyright (C) 2017 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 #include "SensorTest.h" 18 #include <errno.h> 19 20 namespace android { 21 namespace SensorTest { 22 23 // SensorTest container class 24 bool SensorTest::SetUp() { 25 if (mManager == nullptr) { 26 mManager.reset( 27 TestSensorManager::getInstanceForPackage("android.hardware.cts.SensorNativeTest")); 28 } 29 return mManager == nullptr; 30 } 31 32 void SensorTest::TearDown() { 33 if (mManager == nullptr) { 34 mManager.reset(nullptr); 35 } 36 } 37 38 TestSensorManager::TestSensorManager(const char *package) { 39 mManager = ASensorManager_getInstanceForPackage(package); 40 } 41 42 TestSensorManager::~TestSensorManager() { 43 for (int channel : mSensorDirectChannel) { 44 destroyDirectChannel(channel); 45 } 46 mSensorDirectChannel.clear(); 47 } 48 49 TestSensorManager * TestSensorManager::getInstanceForPackage(const char *package) { 50 return new TestSensorManager(package); 51 } 52 53 TestSensor TestSensorManager::getDefaultSensor(int type) { 54 return TestSensor(ASensorManager_getDefaultSensor(mManager, type)); 55 } 56 57 int TestSensorManager::createDirectChannel(const TestSharedMemory &mem) { 58 if (!isValid()) { 59 return -EINVAL; 60 } 61 switch (mem.getType()) { 62 case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY: 63 return createSharedMemoryDirectChannel( 64 mem.getSharedMemoryFd(), mem.getSize()); 65 case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER: 66 return createHardwareBufferDirectChannel( 67 mem.getHardwareBuffer(), mem.getSize()); 68 default: 69 return -1; 70 } 71 } 72 73 int TestSensorManager::createSharedMemoryDirectChannel(int fd, size_t size) { 74 int ret = ASensorManager_createSharedMemoryDirectChannel(mManager, fd, size); 75 if (ret > 0) { 76 mSensorDirectChannel.insert(ret); 77 } 78 return ret; 79 } 80 81 int TestSensorManager::createHardwareBufferDirectChannel( 82 AHardwareBuffer const *buffer, size_t size) { 83 int ret = ASensorManager_createHardwareBufferDirectChannel(mManager, buffer, size); 84 if (ret > 0) { 85 mSensorDirectChannel.insert(ret); 86 } 87 return ret; 88 } 89 90 void TestSensorManager::destroyDirectChannel(int channel) { 91 if (!isValid()) { 92 return; 93 } 94 ASensorManager_destroyDirectChannel(mManager, channel); 95 mSensorDirectChannel.erase(channel); 96 return; 97 } 98 99 int TestSensorManager::configureDirectReport(TestSensor sensor, int channel, int rate) { 100 if (!isValid()) { 101 return -EINVAL; 102 } 103 return ASensorManager_configureDirectReport(mManager, sensor, channel, rate); 104 } 105 106 char * TestSharedMemory::getBuffer() const { 107 return mBuffer; 108 } 109 110 std::vector<ASensorEvent> TestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const { 111 constexpr size_t kEventSize = sizeof(ASensorEvent); 112 constexpr size_t kOffsetSize = offsetof(ASensorEvent, version); 113 constexpr size_t kOffsetAtomicCounter = offsetof(ASensorEvent, reserved0); 114 115 std::vector<ASensorEvent> events; 116 while (offset + kEventSize <= mSize) { 117 int64_t atomicCounter = *reinterpret_cast<uint32_t *>(mBuffer + offset + kOffsetAtomicCounter); 118 if (atomicCounter <= lastCounter) { 119 break; 120 } 121 122 int32_t size = *reinterpret_cast<int32_t *>(mBuffer + offset + kOffsetSize); 123 if (size != kEventSize) { 124 // unknown error, events parsed may be wrong, remove all 125 events.clear(); 126 break; 127 } 128 129 events.push_back(*reinterpret_cast<ASensorEvent *>(mBuffer + offset)); 130 lastCounter = atomicCounter; 131 offset += kEventSize; 132 } 133 134 return events; 135 } 136 137 TestSharedMemory::TestSharedMemory(int type, size_t size) 138 : mType(type), mSize(0), mBuffer(nullptr), 139 mSharedMemoryFd(-1), mHardwareBuffer(nullptr) { 140 bool success = false; 141 switch(type) { 142 case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY: { 143 mSharedMemoryFd = ASharedMemory_create("TestSharedMemory", size); 144 if (mSharedMemoryFd < 0 145 || ASharedMemory_getSize(mSharedMemoryFd) != size) { 146 break; 147 } 148 149 mSize = size; 150 mBuffer = reinterpret_cast<char *>(::mmap( 151 nullptr, mSize, PROT_READ | PROT_WRITE, 152 MAP_SHARED, mSharedMemoryFd, 0)); 153 154 if (mBuffer == MAP_FAILED) { 155 mBuffer = nullptr; 156 break; 157 } 158 success = true; 159 break; 160 } 161 case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER: { 162 AHardwareBuffer_Desc desc = { 163 .width = static_cast<uint32_t>(size), 164 .height = 1, 165 .layers = 1, 166 .usage = AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA 167 | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, 168 .format = AHARDWAREBUFFER_FORMAT_BLOB 169 }; 170 171 // allocate 172 if (AHardwareBuffer_allocate(&desc, &mHardwareBuffer) == 0) { 173 // lock 174 if (AHardwareBuffer_lock(mHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 175 -1, nullptr, reinterpret_cast<void **>(&mBuffer)) == 0) { 176 if (mBuffer != nullptr) { 177 mSize = size; 178 success = true; 179 } 180 } 181 } 182 break; 183 } 184 default: 185 break; 186 } 187 188 if (!success) { 189 release(); 190 } 191 } 192 193 TestSharedMemory::~TestSharedMemory() { 194 release(); 195 } 196 197 void TestSharedMemory::release() { 198 switch(mType) { 199 case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY: { 200 if (mBuffer != nullptr) { 201 ::munmap(mBuffer, mSize); 202 mBuffer = nullptr; 203 } 204 if (mSharedMemoryFd > 0) { 205 ::close(mSharedMemoryFd); 206 mSharedMemoryFd = -1; 207 } 208 mSize = 0; 209 break; 210 } 211 case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER: { 212 if (mHardwareBuffer != nullptr) { 213 if (mBuffer != nullptr) { 214 int32_t fence = -1; 215 AHardwareBuffer_unlock(mHardwareBuffer, &fence); 216 mBuffer = nullptr; 217 } 218 AHardwareBuffer_release(mHardwareBuffer); 219 mHardwareBuffer = nullptr; 220 } 221 mSize = 0; 222 break; 223 } 224 default: 225 break; 226 } 227 if (mSharedMemoryFd > 0 || mSize != 0 || mBuffer != nullptr || mHardwareBuffer != nullptr) { 228 ALOGE("TestSharedMemory %p not properly destructed: " 229 "type %d, shared_memory_fd %d, hardware_buffer %p, size %zu, buffer %p", 230 this, static_cast<int>(mType), mSharedMemoryFd, mHardwareBuffer, mSize, mBuffer); 231 } 232 } 233 234 TestSharedMemory* TestSharedMemory::create(int type, size_t size) { 235 constexpr size_t kMaxSize = 128*1024*1024; // sensor test should not need more than 128M 236 if (size == 0 || size >= kMaxSize) { 237 return nullptr; 238 } 239 240 auto m = new TestSharedMemory(type, size); 241 if (m->mSize != size || m->mBuffer == nullptr) { 242 delete m; 243 m = nullptr; 244 } 245 return m; 246 } 247 } // namespace SensorTest 248 } // namespace android 249