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 #define LOG_TAG "directchannel"
17 #include "directchannel.h"
18
19 #include <cutils/ashmem.h>
20 #include <hardware/sensors.h>
21 #include <utils/Log.h>
22
23 #include <sys/mman.h>
24
25 namespace android {
26
isValid()27 bool DirectChannelBase::isValid() {
28 return mBuffer != nullptr;
29 }
30
getError()31 int DirectChannelBase::getError() {
32 return mError;
33 }
34
write(const sensors_event_t * ev)35 void DirectChannelBase::write(const sensors_event_t * ev) {
36 if (isValid()) {
37 mBuffer->write(ev, 1);
38 }
39 }
40
AshmemDirectChannel(const struct sensors_direct_mem_t * mem)41 AshmemDirectChannel::AshmemDirectChannel(const struct sensors_direct_mem_t *mem) : mAshmemFd(0) {
42 mAshmemFd = mem->handle->data[0];
43
44 if (!::ashmem_valid(mAshmemFd)) {
45 mError = BAD_VALUE;
46 return;
47 }
48
49 if ((size_t)::ashmem_get_size_region(mAshmemFd) != mem->size) {
50 mError = BAD_VALUE;
51 return;
52 }
53
54 mSize = mem->size;
55
56 mBase = ::mmap(NULL, mem->size, PROT_WRITE, MAP_SHARED, mAshmemFd, 0);
57 if (mBase == nullptr) {
58 mError = NO_MEMORY;
59 return;
60 }
61
62 mBuffer = std::unique_ptr<LockfreeBuffer>(new LockfreeBuffer(mBase, mSize));
63 if (!mBuffer) {
64 mError = NO_MEMORY;
65 }
66 }
67
~AshmemDirectChannel()68 AshmemDirectChannel::~AshmemDirectChannel() {
69 if (mBase) {
70 mBuffer = nullptr;
71 ::munmap(mBase, mSize);
72 mBase = nullptr;
73 }
74 ::close(mAshmemFd);
75 }
76
77 ANDROID_SINGLETON_STATIC_INSTANCE(GrallocHalWrapper);
78
GrallocHalWrapper()79 GrallocHalWrapper::GrallocHalWrapper()
80 : mError(NO_INIT), mVersion(-1),
81 mGrallocModule(nullptr), mAllocDevice(nullptr), mGralloc1Device(nullptr),
82 mPfnRetain(nullptr), mPfnRelease(nullptr), mPfnLock(nullptr), mPfnUnlock(nullptr) {
83 const hw_module_t *module;
84 status_t err = ::hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
85 ALOGE_IF(err, "couldn't load %s module (%s)", GRALLOC_HARDWARE_MODULE_ID, strerror(-err));
86
87 if (module == nullptr) {
88 mError = (err < 0) ? err : NO_INIT;
89 }
90
91 switch ((module->module_api_version >> 8) & 0xFF) {
92 case 0:
93 err = ::gralloc_open(module, &mAllocDevice);
94 if (err != NO_ERROR) {
95 ALOGE("cannot open alloc device (%s)", strerror(-err));
96 break;
97 }
98
99 if (mAllocDevice == nullptr) {
100 ALOGE("gralloc_open returns no error, but result is nullptr");
101 err = INVALID_OPERATION;
102 break;
103 }
104
105 // successfully initialized gralloc
106 mGrallocModule = (gralloc_module_t *)module;
107 mVersion = 0;
108 break;
109 case 1:
110 err = ::gralloc1_open(module, &mGralloc1Device);
111 if (err != NO_ERROR) {
112 ALOGE("cannot open gralloc1 device (%s)", strerror(-err));
113 break;
114 }
115
116 if (mGralloc1Device == nullptr || mGralloc1Device->getFunction == nullptr) {
117 ALOGE("gralloc1_open returns no error, but result is nullptr");
118 err = INVALID_OPERATION;
119 break;
120 }
121
122 mPfnRetain = (GRALLOC1_PFN_RETAIN)(mGralloc1Device->getFunction(mGralloc1Device,
123 GRALLOC1_FUNCTION_RETAIN));
124 mPfnRelease = (GRALLOC1_PFN_RELEASE)(mGralloc1Device->getFunction(mGralloc1Device,
125 GRALLOC1_FUNCTION_RELEASE));
126 mPfnLock = (GRALLOC1_PFN_LOCK)(mGralloc1Device->getFunction(mGralloc1Device,
127 GRALLOC1_FUNCTION_LOCK));
128 mPfnUnlock = (GRALLOC1_PFN_UNLOCK)(mGralloc1Device->getFunction(mGralloc1Device,
129 GRALLOC1_FUNCTION_UNLOCK));
130 if (mPfnRetain == nullptr || mPfnRelease == nullptr
131 || mPfnLock == nullptr || mPfnUnlock == nullptr) {
132 ALOGE("Function pointer for retain, release, lock and unlock are %p, %p, %p, %p",
133 mPfnRetain, mPfnRelease, mPfnLock, mPfnUnlock);
134 err = BAD_VALUE;
135 break;
136 }
137
138 // successfully initialized gralloc1
139 mGrallocModule = (gralloc_module_t *)module;
140 mVersion = 1;
141 break;
142 default:
143 ALOGE("Unknown version, not supported");
144 break;
145 }
146 mError = err;
147 }
148
~GrallocHalWrapper()149 GrallocHalWrapper::~GrallocHalWrapper() {
150 if (mAllocDevice != nullptr) {
151 ::gralloc_close(mAllocDevice);
152 }
153 }
154
registerBuffer(const native_handle_t * handle)155 int GrallocHalWrapper::registerBuffer(const native_handle_t *handle) {
156 switch (mVersion) {
157 case 0:
158 return mGrallocModule->registerBuffer(mGrallocModule, handle);
159 case 1:
160 return mapGralloc1Error(mPfnRetain(mGralloc1Device, handle));
161 default:
162 return NO_INIT;
163 }
164 }
165
unregisterBuffer(const native_handle_t * handle)166 int GrallocHalWrapper::unregisterBuffer(const native_handle_t *handle) {
167 switch (mVersion) {
168 case 0:
169 return mGrallocModule->unregisterBuffer(mGrallocModule, handle);
170 case 1:
171 return mapGralloc1Error(mPfnRelease(mGralloc1Device, handle));
172 default:
173 return NO_INIT;
174 }
175 }
176
lock(const native_handle_t * handle,int usage,int l,int t,int w,int h,void ** vaddr)177 int GrallocHalWrapper::lock(const native_handle_t *handle,
178 int usage, int l, int t, int w, int h, void **vaddr) {
179 switch (mVersion) {
180 case 0:
181 return mGrallocModule->lock(mGrallocModule, handle, usage, l, t, w, h, vaddr);
182 case 1: {
183 const gralloc1_rect_t rect = {
184 .left = l,
185 .top = t,
186 .width = w,
187 .height = h
188 };
189 return mapGralloc1Error(mPfnLock(mGralloc1Device, handle,
190 GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
191 GRALLOC1_CONSUMER_USAGE_NONE,
192 &rect, vaddr, -1));
193 }
194 default:
195 return NO_INIT;
196 }
197 }
198
unlock(const native_handle_t * handle)199 int GrallocHalWrapper::unlock(const native_handle_t *handle) {
200 switch (mVersion) {
201 case 0:
202 return mGrallocModule->unlock(mGrallocModule, handle);
203 case 1: {
204 int32_t dummy;
205 return mapGralloc1Error(mPfnUnlock(mGralloc1Device, handle, &dummy));
206 }
207 default:
208 return NO_INIT;
209 }
210 }
211
mapGralloc1Error(int grallocError)212 int GrallocHalWrapper::mapGralloc1Error(int grallocError) {
213 switch (grallocError) {
214 case GRALLOC1_ERROR_NONE:
215 return NO_ERROR;
216 case GRALLOC1_ERROR_BAD_DESCRIPTOR:
217 case GRALLOC1_ERROR_BAD_HANDLE:
218 case GRALLOC1_ERROR_BAD_VALUE:
219 return BAD_VALUE;
220 case GRALLOC1_ERROR_NOT_SHARED:
221 case GRALLOC1_ERROR_NO_RESOURCES:
222 return NO_MEMORY;
223 case GRALLOC1_ERROR_UNDEFINED:
224 case GRALLOC1_ERROR_UNSUPPORTED:
225 return INVALID_OPERATION;
226 default:
227 return UNKNOWN_ERROR;
228 }
229 }
230
GrallocDirectChannel(const struct sensors_direct_mem_t * mem)231 GrallocDirectChannel::GrallocDirectChannel(const struct sensors_direct_mem_t *mem)
232 : mNativeHandle(nullptr) {
233 if (mem->handle == nullptr) {
234 ALOGE("mem->handle == nullptr");
235 mError = BAD_VALUE;
236 return;
237 }
238
239 mNativeHandle = ::native_handle_clone(mem->handle);
240 if (mNativeHandle == nullptr) {
241 ALOGE("clone mem->handle failed...");
242 mError = NO_MEMORY;
243 return;
244 }
245
246 mError = GrallocHalWrapper::getInstance().registerBuffer(mNativeHandle);
247 if (mError != NO_ERROR) {
248 ALOGE("registerBuffer failed");
249 return;
250 }
251
252 mError = GrallocHalWrapper::getInstance().lock(mNativeHandle,
253 GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, mem->size, 1, &mBase);
254 if (mError != NO_ERROR) {
255 ALOGE("lock buffer failed");
256 return;
257 }
258
259 if (mBase == nullptr) {
260 ALOGE("lock buffer => nullptr");
261 mError = NO_MEMORY;
262 return;
263 }
264
265 mSize = mem->size;
266 mBuffer = std::make_unique<LockfreeBuffer>(mBase, mSize);
267 if (!mBuffer) {
268 mError = NO_MEMORY;
269 return;
270 }
271
272 mError = NO_ERROR;
273 }
274
~GrallocDirectChannel()275 GrallocDirectChannel::~GrallocDirectChannel() {
276 if (mNativeHandle != nullptr) {
277 if (mBase) {
278 mBuffer = nullptr;
279 GrallocHalWrapper::getInstance().unlock(mNativeHandle);
280 mBase = nullptr;
281 }
282 GrallocHalWrapper::getInstance().unregisterBuffer(mNativeHandle);
283 ::native_handle_close(mNativeHandle);
284 ::native_handle_delete(mNativeHandle);
285 mNativeHandle = nullptr;
286 }
287 }
288
289 } // namespace android
290