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
SetUp()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
TearDown()32 void SensorTest::TearDown() {
33 if (mManager == nullptr) {
34 mManager.reset(nullptr);
35 }
36 }
37
TestSensorManager(const char * package)38 TestSensorManager::TestSensorManager(const char *package) {
39 mManager = ASensorManager_getInstanceForPackage(package);
40 }
41
~TestSensorManager()42 TestSensorManager::~TestSensorManager() {
43 for (int channel : mSensorDirectChannel) {
44 destroyDirectChannel(channel);
45 }
46 mSensorDirectChannel.clear();
47 }
48
getInstanceForPackage(const char * package)49 TestSensorManager * TestSensorManager::getInstanceForPackage(const char *package) {
50 return new TestSensorManager(package);
51 }
52
getDefaultSensor(int type)53 TestSensor TestSensorManager::getDefaultSensor(int type) {
54 return TestSensor(ASensorManager_getDefaultSensor(mManager, type));
55 }
56
createDirectChannel(const TestSharedMemory & mem)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
createSharedMemoryDirectChannel(int fd,size_t size)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
createHardwareBufferDirectChannel(AHardwareBuffer const * buffer,size_t size)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
destroyDirectChannel(int channel)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
configureDirectReport(TestSensor sensor,int channel,int rate)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
getBuffer() const106 char * TestSharedMemory::getBuffer() const {
107 return mBuffer;
108 }
109
parseEvents(int64_t lastCounter,size_t offset) const110 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
TestSharedMemory(int type,size_t size)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 .format = AHARDWAREBUFFER_FORMAT_BLOB,
167 .usage = AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA
168 | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
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
~TestSharedMemory()193 TestSharedMemory::~TestSharedMemory() {
194 release();
195 }
196
release()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
create(int type,size_t size)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