• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "SensorsTestSharedMemory.h"
18 
19 #include <log/log.h>
20 
21 #include <sys/mman.h>
22 #include <cinttypes>
23 
24 using namespace ::android::hardware::sensors::V1_0;
25 
getSharedMemInfo() const26 SharedMemInfo SensorsTestSharedMemory::getSharedMemInfo() const {
27     SharedMemInfo mem = {.type = mType,
28                          .format = SharedMemFormat::SENSORS_EVENT,
29                          .size = static_cast<uint32_t>(mSize),
30                          .memoryHandle = mNativeHandle};
31     return mem;
32 }
33 
getBuffer() const34 char* SensorsTestSharedMemory::getBuffer() const {
35     return mBuffer;
36 }
37 
getSize() const38 size_t SensorsTestSharedMemory::getSize() const {
39     return mSize;
40 }
41 
parseEvents(int64_t lastCounter,size_t offset) const42 std::vector<Event> SensorsTestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const {
43     constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
44     constexpr size_t kOffsetSize = static_cast<size_t>(SensorsEventFormatOffset::SIZE_FIELD);
45     constexpr size_t kOffsetToken = static_cast<size_t>(SensorsEventFormatOffset::REPORT_TOKEN);
46     constexpr size_t kOffsetType = static_cast<size_t>(SensorsEventFormatOffset::SENSOR_TYPE);
47     constexpr size_t kOffsetAtomicCounter =
48         static_cast<size_t>(SensorsEventFormatOffset::ATOMIC_COUNTER);
49     constexpr size_t kOffsetTimestamp = static_cast<size_t>(SensorsEventFormatOffset::TIMESTAMP);
50     constexpr size_t kOffsetData = static_cast<size_t>(SensorsEventFormatOffset::DATA);
51 
52     std::vector<Event> events;
53     std::vector<float> data(16);
54 
55     while (offset + kEventSize <= mSize) {
56         int64_t atomicCounter =
57             *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter);
58         if (atomicCounter <= lastCounter) {
59             ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter,
60                   lastCounter);
61             break;
62         }
63 
64         int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize);
65         if (size != kEventSize) {
66             // unknown error, events parsed may be wrong, remove all
67             events.clear();
68             break;
69         }
70 
71         int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken);
72         int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType);
73         int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp);
74 
75         ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32
76               ", timestamp %" PRId64,
77               offset, atomicCounter, token, type, timestamp);
78 
79         Event event = {
80             .timestamp = timestamp,
81             .sensorHandle = token,
82             .sensorType = static_cast<SensorType>(type),
83         };
84         event.u.data = android::hardware::hidl_array<float, 16>(
85             reinterpret_cast<float*>(mBuffer + offset + kOffsetData));
86 
87         events.push_back(event);
88 
89         lastCounter = atomicCounter;
90         offset += kEventSize;
91     }
92 
93     return events;
94 }
95 
SensorsTestSharedMemory(SharedMemType type,size_t size)96 SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size)
97     : mType(type), mSize(0), mBuffer(nullptr) {
98     native_handle_t* handle = nullptr;
99     char* buffer = nullptr;
100     switch (type) {
101         case SharedMemType::ASHMEM: {
102             int fd;
103             handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/);
104             if (handle != nullptr) {
105                 handle->data[0] = fd = ::ashmem_create_region("SensorsTestSharedMemory", size);
106                 if (handle->data[0] > 0) {
107                     // memory is pinned by default
108                     buffer = static_cast<char*>(
109                         ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
110                     if (buffer != reinterpret_cast<char*>(MAP_FAILED)) {
111                         break;
112                     }
113                     ::native_handle_close(handle);
114                 }
115                 ::native_handle_delete(handle);
116                 handle = nullptr;
117             }
118             break;
119         }
120         case SharedMemType::GRALLOC: {
121             mGrallocWrapper = std::make_unique<::android::GrallocWrapper>();
122             if (mGrallocWrapper->getAllocator() == nullptr ||
123                 mGrallocWrapper->getMapper() == nullptr) {
124                 break;
125             }
126             using android::hardware::graphics::common::V1_0::BufferUsage;
127             using android::hardware::graphics::common::V1_0::PixelFormat;
128             mapper2::IMapper::BufferDescriptorInfo buf_desc_info = {
129                 .width = static_cast<uint32_t>(size),
130                 .height = 1,
131                 .layerCount = 1,
132                 .usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA |
133                                                BufferUsage::CPU_READ_OFTEN),
134                 .format = PixelFormat::BLOB};
135 
136             handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info));
137             if (handle != nullptr) {
138                 mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width),
139                                               static_cast<int32_t>(buf_desc_info.height)};
140                 buffer = static_cast<char*>(
141                     mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1));
142                 if (buffer != nullptr) {
143                     break;
144                 }
145                 mGrallocWrapper->freeBuffer(handle);
146                 handle = nullptr;
147             }
148             break;
149         }
150         default:
151             break;
152     }
153 
154     if (buffer != nullptr) {
155         mNativeHandle = handle;
156         mSize = size;
157         mBuffer = buffer;
158     }
159 }
160 
~SensorsTestSharedMemory()161 SensorsTestSharedMemory::~SensorsTestSharedMemory() {
162     switch (mType) {
163         case SharedMemType::ASHMEM: {
164             if (mSize != 0) {
165                 ::munmap(mBuffer, mSize);
166                 mBuffer = nullptr;
167 
168                 ::native_handle_close(mNativeHandle);
169                 ::native_handle_delete(mNativeHandle);
170 
171                 mNativeHandle = nullptr;
172                 mSize = 0;
173             }
174             break;
175         }
176         case SharedMemType::GRALLOC: {
177             if (mSize != 0) {
178                 mGrallocWrapper->unlock(mNativeHandle);
179                 mGrallocWrapper->freeBuffer(mNativeHandle);
180 
181                 mNativeHandle = nullptr;
182                 mSize = 0;
183             }
184             break;
185         }
186         default: {
187             if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) {
188                 ALOGE(
189                     "SensorsTestSharedMemory %p not properly destructed: "
190                     "type %d, native handle %p, size %zu, buffer %p",
191                     this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer);
192             }
193             break;
194         }
195     }
196 }
197 
create(SharedMemType type,size_t size)198 SensorsTestSharedMemory* SensorsTestSharedMemory::create(SharedMemType type, size_t size) {
199     constexpr size_t kMaxSize = 128 * 1024 * 1024;  // sensor test should not need more than 128M
200     if (size == 0 || size >= kMaxSize) {
201         return nullptr;
202     }
203 
204     auto m = new SensorsTestSharedMemory(type, size);
205     if (m->mSize != size || m->mBuffer == nullptr) {
206         delete m;
207         m = nullptr;
208     }
209     return m;
210 }
211