Home | History | Annotate | Download | only in sensorhal
      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 
     27 bool DirectChannelBase::isValid() {
     28     return mBuffer != nullptr;
     29 }
     30 
     31 int DirectChannelBase::getError() {
     32     return mError;
     33 }
     34 
     35 void DirectChannelBase::write(const sensors_event_t * ev) {
     36     if (isValid()) {
     37         mBuffer->write(ev, 1);
     38     }
     39 }
     40 
     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 
     68 AshmemDirectChannel::~AshmemDirectChannel() {
     69     if (mBase) {
     70         mBuffer = nullptr;
     71         ::munmap(mBase, mSize);
     72         mBase = nullptr;
     73     }
     74     ::close(mAshmemFd);
     75 }
     76 
     77 bool AshmemDirectChannel::memoryMatches(const struct sensors_direct_mem_t * /*mem*/) const {
     78     return false;
     79 }
     80 
     81 ANDROID_SINGLETON_STATIC_INSTANCE(GrallocHalWrapper);
     82 
     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 
    172 GrallocHalWrapper::~GrallocHalWrapper() {
    173     if (mAllocDevice != nullptr) {
    174         ::gralloc_close(mAllocDevice);
    175     }
    176 }
    177 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    329 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