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