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
memoryMatches(const struct sensors_direct_mem_t *) const77 bool AshmemDirectChannel::memoryMatches(const struct sensors_direct_mem_t * /*mem*/) const {
78 return false;
79 }
80
81 ANDROID_SINGLETON_STATIC_INSTANCE(GrallocHalWrapper);
82
GrallocHalWrapper()83 GrallocHalWrapper::GrallocHalWrapper()
84 : mError(NO_INIT), mVersion(-1),
85 mGrallocModule(nullptr), mAllocDevice(nullptr), mGralloc1Device(nullptr),
86 mPfnRetain(nullptr), mPfnRelease(nullptr), mPfnLock(nullptr), mPfnUnlock(nullptr),
87 mUnregisterImplyDelete(false) {
88 const hw_module_t *module;
89 status_t err = ::hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
90 ALOGE_IF(err, "couldn't load %s module (%s)", GRALLOC_HARDWARE_MODULE_ID, strerror(-err));
91
92 if (module == nullptr) {
93 mError = (err < 0) ? err : NO_INIT;
94 }
95
96 switch ((module->module_api_version >> 8) & 0xFF) {
97 case 0:
98 err = ::gralloc_open(module, &mAllocDevice);
99 if (err != NO_ERROR) {
100 ALOGE("cannot open alloc device (%s)", strerror(-err));
101 break;
102 }
103
104 if (mAllocDevice == nullptr) {
105 ALOGE("gralloc_open returns no error, but result is nullptr");
106 err = INVALID_OPERATION;
107 break;
108 }
109
110 // successfully initialized gralloc
111 mGrallocModule = (gralloc_module_t *)module;
112 mVersion = 0;
113 break;
114 case 1: {
115 err = ::gralloc1_open(module, &mGralloc1Device);
116 if (err != NO_ERROR) {
117 ALOGE("cannot open gralloc1 device (%s)", strerror(-err));
118 break;
119 }
120
121 if (mGralloc1Device == nullptr || mGralloc1Device->getFunction == nullptr) {
122 ALOGE("gralloc1_open returns no error, but result is nullptr");
123 err = INVALID_OPERATION;
124 break;
125 }
126
127 mPfnRetain = (GRALLOC1_PFN_RETAIN)(mGralloc1Device->getFunction(mGralloc1Device,
128 GRALLOC1_FUNCTION_RETAIN));
129 mPfnRelease = (GRALLOC1_PFN_RELEASE)(mGralloc1Device->getFunction(mGralloc1Device,
130 GRALLOC1_FUNCTION_RELEASE));
131 mPfnLock = (GRALLOC1_PFN_LOCK)(mGralloc1Device->getFunction(mGralloc1Device,
132 GRALLOC1_FUNCTION_LOCK));
133 mPfnUnlock = (GRALLOC1_PFN_UNLOCK)(mGralloc1Device->getFunction(mGralloc1Device,
134 GRALLOC1_FUNCTION_UNLOCK));
135 mPfnGetBackingStore = (GRALLOC1_PFN_GET_BACKING_STORE)
136 (mGralloc1Device->getFunction(mGralloc1Device,
137 GRALLOC1_FUNCTION_GET_BACKING_STORE));
138 if (mPfnRetain == nullptr || mPfnRelease == nullptr
139 || mPfnLock == nullptr || mPfnUnlock == nullptr
140 || mPfnGetBackingStore == nullptr) {
141 ALOGE("Function pointer for retain, release, lock, unlock and getBackingStore are "
142 "%p, %p, %p, %p, %p",
143 mPfnRetain, mPfnRelease, mPfnLock, mPfnUnlock, mPfnGetBackingStore);
144 err = BAD_VALUE;
145 break;
146 }
147
148
149 int32_t caps[GRALLOC1_LAST_CAPABILITY];
150 uint32_t n_cap = GRALLOC1_LAST_CAPABILITY;
151 mGralloc1Device->getCapabilities(mGralloc1Device, &n_cap, caps);
152 for (size_t i = 0; i < n_cap; ++i) {
153 if (caps[i] == GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE) {
154 mUnregisterImplyDelete = true;
155 }
156 }
157 ALOGI("gralloc hal %ssupport RELEASE_IMPLY_DELETE",
158 mUnregisterImplyDelete ? "" : "does not ");
159
160 // successfully initialized gralloc1
161 mGrallocModule = (gralloc_module_t *)module;
162 mVersion = 1;
163 break;
164 }
165 default:
166 ALOGE("Unknown version, not supported");
167 break;
168 }
169 mError = err;
170 }
171
~GrallocHalWrapper()172 GrallocHalWrapper::~GrallocHalWrapper() {
173 if (mAllocDevice != nullptr) {
174 ::gralloc_close(mAllocDevice);
175 }
176 }
177
registerBuffer(const native_handle_t * handle)178 int GrallocHalWrapper::registerBuffer(const native_handle_t *handle) {
179 switch (mVersion) {
180 case 0:
181 return mGrallocModule->registerBuffer(mGrallocModule, handle);
182 case 1:
183 return mapGralloc1Error(mPfnRetain(mGralloc1Device, handle));
184 default:
185 return NO_INIT;
186 }
187 }
188
unregisterBuffer(const native_handle_t * handle)189 int GrallocHalWrapper::unregisterBuffer(const native_handle_t *handle) {
190 switch (mVersion) {
191 case 0:
192 return mGrallocModule->unregisterBuffer(mGrallocModule, handle);
193 case 1:
194 return mapGralloc1Error(mPfnRelease(mGralloc1Device, handle));
195 default:
196 return NO_INIT;
197 }
198 }
199
lock(const native_handle_t * handle,int usage,int l,int t,int w,int h,void ** vaddr)200 int GrallocHalWrapper::lock(const native_handle_t *handle,
201 int usage, int l, int t, int w, int h, void **vaddr) {
202 switch (mVersion) {
203 case 0:
204 return mGrallocModule->lock(mGrallocModule, handle, usage, l, t, w, h, vaddr);
205 case 1: {
206 const gralloc1_rect_t rect = {
207 .left = l,
208 .top = t,
209 .width = w,
210 .height = h
211 };
212 return mapGralloc1Error(mPfnLock(mGralloc1Device, handle,
213 GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
214 GRALLOC1_CONSUMER_USAGE_NONE,
215 &rect, vaddr, -1));
216 }
217 default:
218 return NO_INIT;
219 }
220 }
221
unlock(const native_handle_t * handle)222 int GrallocHalWrapper::unlock(const native_handle_t *handle) {
223 switch (mVersion) {
224 case 0:
225 return mGrallocModule->unlock(mGrallocModule, handle);
226 case 1: {
227 int32_t dummy;
228 return mapGralloc1Error(mPfnUnlock(mGralloc1Device, handle, &dummy));
229 }
230 default:
231 return NO_INIT;
232 }
233 }
234
isSameMemory(const native_handle_t * h1,const native_handle_t * h2)235 bool GrallocHalWrapper::isSameMemory(const native_handle_t *h1, const native_handle_t *h2) {
236 switch (mVersion) {
237 case 0:
238 return false; // version 1.0 cannot compare two memory
239 case 1: {
240 gralloc1_backing_store_t s1, s2;
241
242 return mPfnGetBackingStore(mGralloc1Device, h1, &s1) == GRALLOC1_ERROR_NONE
243 && mPfnGetBackingStore(mGralloc1Device, h2, &s2) == GRALLOC1_ERROR_NONE
244 && s1 == s2;
245 }
246 }
247 return false;
248 }
249
mapGralloc1Error(int grallocError)250 int GrallocHalWrapper::mapGralloc1Error(int grallocError) {
251 switch (grallocError) {
252 case GRALLOC1_ERROR_NONE:
253 return NO_ERROR;
254 case GRALLOC1_ERROR_BAD_DESCRIPTOR:
255 case GRALLOC1_ERROR_BAD_HANDLE:
256 case GRALLOC1_ERROR_BAD_VALUE:
257 return BAD_VALUE;
258 case GRALLOC1_ERROR_NOT_SHARED:
259 case GRALLOC1_ERROR_NO_RESOURCES:
260 return NO_MEMORY;
261 case GRALLOC1_ERROR_UNDEFINED:
262 case GRALLOC1_ERROR_UNSUPPORTED:
263 return INVALID_OPERATION;
264 default:
265 return UNKNOWN_ERROR;
266 }
267 }
268
GrallocDirectChannel(const struct sensors_direct_mem_t * mem)269 GrallocDirectChannel::GrallocDirectChannel(const struct sensors_direct_mem_t *mem)
270 : mNativeHandle(nullptr) {
271 if (mem->handle == nullptr) {
272 ALOGE("mem->handle == nullptr");
273 mError = BAD_VALUE;
274 return;
275 }
276
277 mNativeHandle = ::native_handle_clone(mem->handle);
278 if (mNativeHandle == nullptr) {
279 ALOGE("clone mem->handle failed...");
280 mError = NO_MEMORY;
281 return;
282 }
283
284 mError = GrallocHalWrapper::getInstance().registerBuffer(mNativeHandle);
285 if (mError != NO_ERROR) {
286 ALOGE("registerBuffer failed");
287 return;
288 }
289
290 mError = GrallocHalWrapper::getInstance().lock(mNativeHandle,
291 GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, mem->size, 1, &mBase);
292 if (mError != NO_ERROR) {
293 ALOGE("lock buffer failed");
294 return;
295 }
296
297 if (mBase == nullptr) {
298 ALOGE("lock buffer => nullptr");
299 mError = NO_MEMORY;
300 return;
301 }
302
303 mSize = mem->size;
304 mBuffer = std::make_unique<LockfreeBuffer>(mBase, mSize);
305 if (!mBuffer) {
306 mError = NO_MEMORY;
307 return;
308 }
309
310 mError = NO_ERROR;
311 }
312
~GrallocDirectChannel()313 GrallocDirectChannel::~GrallocDirectChannel() {
314 if (mNativeHandle != nullptr) {
315 if (mBase) {
316 mBuffer = nullptr;
317 GrallocHalWrapper::getInstance().unlock(mNativeHandle);
318 mBase = nullptr;
319 }
320 GrallocHalWrapper::getInstance().unregisterBuffer(mNativeHandle);
321 if (!GrallocHalWrapper::getInstance().unregisterImplyDelete()) {
322 ::native_handle_close(mNativeHandle);
323 ::native_handle_delete(mNativeHandle);
324 }
325 mNativeHandle = nullptr;
326 }
327 }
328
memoryMatches(const struct sensors_direct_mem_t * mem) const329 bool GrallocDirectChannel::memoryMatches(const struct sensors_direct_mem_t *mem) const {
330 return mem->type == SENSOR_DIRECT_MEM_TYPE_GRALLOC &&
331 GrallocHalWrapper::getInstance().isSameMemory(mem->handle, mNativeHandle);
332 }
333
334 } // namespace android
335