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