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 17 #define LOG_TAG "HandleImporter" 18 #include "HandleImporter.h" 19 #include <log/log.h> 20 21 namespace android { 22 namespace hardware { 23 namespace camera { 24 namespace common { 25 namespace V1_0 { 26 namespace helper { 27 28 using MapperError = android::hardware::graphics::mapper::V2_0::Error; 29 30 HandleImporter::HandleImporter() : mInitialized(false) {} 31 32 void HandleImporter::initializeLocked() { 33 if (mInitialized) { 34 return; 35 } 36 37 mMapper = IMapper::getService(); 38 if (mMapper == nullptr) { 39 ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__); 40 return; 41 } 42 43 mInitialized = true; 44 return; 45 } 46 47 void HandleImporter::cleanup() { 48 mMapper.clear(); 49 mInitialized = false; 50 } 51 52 // In IComposer, any buffer_handle_t is owned by the caller and we need to 53 // make a clone for hwcomposer2. We also need to translate empty handle 54 // to nullptr. This function does that, in-place. 55 bool HandleImporter::importBuffer(buffer_handle_t& handle) { 56 if (!handle->numFds && !handle->numInts) { 57 handle = nullptr; 58 return true; 59 } 60 61 Mutex::Autolock lock(mLock); 62 if (!mInitialized) { 63 initializeLocked(); 64 } 65 66 if (mMapper == nullptr) { 67 ALOGE("%s: mMapper is null!", __FUNCTION__); 68 return false; 69 } 70 71 MapperError error; 72 buffer_handle_t importedHandle; 73 auto ret = mMapper->importBuffer( 74 hidl_handle(handle), 75 [&](const auto& tmpError, const auto& tmpBufferHandle) { 76 error = tmpError; 77 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle); 78 }); 79 80 if (!ret.isOk()) { 81 ALOGE("%s: mapper importBuffer failed: %s", 82 __FUNCTION__, ret.description().c_str()); 83 return false; 84 } 85 86 if (error != MapperError::NONE) { 87 return false; 88 } 89 90 handle = importedHandle; 91 92 return true; 93 } 94 95 void HandleImporter::freeBuffer(buffer_handle_t handle) { 96 if (!handle) { 97 return; 98 } 99 100 Mutex::Autolock lock(mLock); 101 if (mMapper == nullptr) { 102 ALOGE("%s: mMapper is null!", __FUNCTION__); 103 return; 104 } 105 106 auto ret = mMapper->freeBuffer(const_cast<native_handle_t*>(handle)); 107 if (!ret.isOk()) { 108 ALOGE("%s: mapper freeBuffer failed: %s", 109 __FUNCTION__, ret.description().c_str()); 110 } 111 } 112 113 bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const { 114 if (handle == nullptr || handle->numFds == 0) { 115 fd = -1; 116 } else if (handle->numFds == 1) { 117 fd = dup(handle->data[0]); 118 if (fd < 0) { 119 ALOGE("failed to dup fence fd %d", handle->data[0]); 120 return false; 121 } 122 } else { 123 ALOGE("invalid fence handle with %d file descriptors", 124 handle->numFds); 125 return false; 126 } 127 128 return true; 129 } 130 131 void HandleImporter::closeFence(int fd) const { 132 if (fd >= 0) { 133 close(fd); 134 } 135 } 136 137 } // namespace helper 138 } // namespace V1_0 139 } // namespace common 140 } // namespace camera 141 } // namespace hardware 142 } // namespace android 143