1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "buffer_handle.h" 17#include "buffer_handle_utils.h" 18 19#include <cstdlib> 20#include <securec.h> 21 22#include <hilog/log.h> 23#include <message_parcel.h> 24#include <unistd.h> 25 26#undef LOG_DOMAIN 27#define LOG_DOMAIN 0xD001400 28#undef LOG_TAG 29#define LOG_TAG "graphicutils" 30#define UTILS_LOGF(...) (void)HILOG_FATAL(LOG_CORE, __VA_ARGS__) 31#define UTILS_LOGE(...) (void)HILOG_ERROR(LOG_CORE, __VA_ARGS__) 32#define UTILS_LOGW(...) (void)HILOG_WARN(LOG_CORE, __VA_ARGS__) 33#define UTILS_LOGI(...) (void)HILOG_INFO(LOG_CORE, __VA_ARGS__) 34#define UTILS_LOGD(...) (void)HILOG_DEBUG(LOG_CORE, __VA_ARGS__) 35#define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024 36 37BufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts) 38{ 39 if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) { 40 UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager"); 41 return nullptr; 42 } 43 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts)); 44 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize)); 45 if (handle != nullptr) { 46 errno_t ret = memset_s(handle, handleSize, 0, handleSize); 47 if (ret != 0) { 48 UTILS_LOGE("memset_s error, ret is %{public}d", ret); 49 free(handle); 50 return nullptr; 51 } 52 handle->fd = -1; 53 for (uint32_t i = 0; i < reserveFds; i++) { 54 handle->reserve[i] = -1; 55 } 56 handle->reserveFds = reserveFds; 57 handle->reserveInts = reserveInts; 58 } else { 59 UTILS_LOGE("AllocateBufferHandle malloc %{public}zu failed", handleSize); 60 } 61 return handle; 62} 63 64int32_t FreeBufferHandle(BufferHandle *handle) 65{ 66 if (handle == nullptr) { 67 UTILS_LOGW("FreeBufferHandle with nullptr handle"); 68 return 0; 69 } 70 if (handle->fd >= 0) { 71 close(handle->fd); 72 handle->fd = -1; 73 } 74 const uint32_t reserveFds = handle->reserveFds; 75 for (uint32_t i = 0; i < reserveFds; i++) { 76 if (handle->reserve[i] >= 0) { 77 close(handle->reserve[i]); 78 handle->reserve[i] = -1; 79 } 80 } 81 free(handle); 82 return 0; 83} 84 85namespace OHOS { 86bool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle) 87{ 88 if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) || 89 !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) || 90 !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) || 91 !parcel.WriteUint64(handle.phyAddr)) { 92 UTILS_LOGE("%{public}s a lot failed", __func__); 93 return false; 94 } 95 bool validFd = (handle.fd >= 0); 96 if (!parcel.WriteBool(validFd)) { 97 UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__); 98 return false; 99 } 100 if (validFd && !parcel.WriteFileDescriptor(handle.fd)) { 101 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__); 102 return false; 103 } 104 105 for (uint32_t i = 0; i < handle.reserveFds; i++) { 106 if (!parcel.WriteFileDescriptor(handle.reserve[i])) { 107 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__); 108 return false; 109 } 110 } 111 for (uint32_t j = 0; j < handle.reserveInts; j++) { 112 if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) { 113 UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__); 114 return false; 115 } 116 } 117 return true; 118} 119 120BufferHandle *ReadBufferHandle(MessageParcel &parcel) 121{ 122 uint32_t reserveFds = 0; 123 uint32_t reserveInts = 0; 124 if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) { 125 UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__); 126 return nullptr; 127 } 128 129 BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts); 130 if (handle == nullptr) { 131 UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__); 132 return nullptr; 133 } 134 135 if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) || 136 !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) || 137 !parcel.ReadUint64(handle->phyAddr)) { 138 UTILS_LOGE("%{public}s a lot failed", __func__); 139 FreeBufferHandle(handle); 140 return nullptr; 141 } 142 143 bool validFd = false; 144 if (!parcel.ReadBool(validFd)) { 145 UTILS_LOGE("%{public}s ReadBool validFd failed", __func__); 146 FreeBufferHandle(handle); 147 return nullptr; 148 } 149 if (validFd) { 150 handle->fd = parcel.ReadFileDescriptor(); 151 if (handle->fd == -1) { 152 UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__); 153 FreeBufferHandle(handle); 154 return nullptr; 155 } 156 } 157 158 for (uint32_t i = 0; i < handle->reserveFds; i++) { 159 handle->reserve[i] = parcel.ReadFileDescriptor(); 160 if (handle->reserve[i] == -1) { 161 UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__); 162 FreeBufferHandle(handle); 163 return nullptr; 164 } 165 } 166 for (uint32_t j = 0; j < handle->reserveInts; j++) { 167 if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) { 168 UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__); 169 FreeBufferHandle(handle); 170 return nullptr; 171 } 172 } 173 return handle; 174} 175} // namespace OHOS 176