132a6e48fSopenharmony_ci/* 232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License. 532a6e48fSopenharmony_ci * You may obtain a copy of the License at 632a6e48fSopenharmony_ci * 732a6e48fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 832a6e48fSopenharmony_ci * 932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and 1332a6e48fSopenharmony_ci * limitations under the License. 1432a6e48fSopenharmony_ci */ 1532a6e48fSopenharmony_ci 1632a6e48fSopenharmony_ci#include "buffer_handle.h" 1732a6e48fSopenharmony_ci#include "buffer_handle_utils.h" 1832a6e48fSopenharmony_ci 1932a6e48fSopenharmony_ci#include <cstdlib> 2032a6e48fSopenharmony_ci#include <securec.h> 2132a6e48fSopenharmony_ci 2232a6e48fSopenharmony_ci#include <hilog/log.h> 2332a6e48fSopenharmony_ci#include <message_parcel.h> 2432a6e48fSopenharmony_ci#include <unistd.h> 2532a6e48fSopenharmony_ci 2632a6e48fSopenharmony_ci#undef LOG_DOMAIN 2732a6e48fSopenharmony_ci#define LOG_DOMAIN 0xD001400 2832a6e48fSopenharmony_ci#undef LOG_TAG 2932a6e48fSopenharmony_ci#define LOG_TAG "graphicutils" 3032a6e48fSopenharmony_ci#define UTILS_LOGF(...) (void)HILOG_FATAL(LOG_CORE, __VA_ARGS__) 3132a6e48fSopenharmony_ci#define UTILS_LOGE(...) (void)HILOG_ERROR(LOG_CORE, __VA_ARGS__) 3232a6e48fSopenharmony_ci#define UTILS_LOGW(...) (void)HILOG_WARN(LOG_CORE, __VA_ARGS__) 3332a6e48fSopenharmony_ci#define UTILS_LOGI(...) (void)HILOG_INFO(LOG_CORE, __VA_ARGS__) 3432a6e48fSopenharmony_ci#define UTILS_LOGD(...) (void)HILOG_DEBUG(LOG_CORE, __VA_ARGS__) 3532a6e48fSopenharmony_ci#define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024 3632a6e48fSopenharmony_ci 3732a6e48fSopenharmony_ciBufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts) 3832a6e48fSopenharmony_ci{ 3932a6e48fSopenharmony_ci if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) { 4032a6e48fSopenharmony_ci UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager"); 4132a6e48fSopenharmony_ci return nullptr; 4232a6e48fSopenharmony_ci } 4332a6e48fSopenharmony_ci size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts)); 4432a6e48fSopenharmony_ci BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize)); 4532a6e48fSopenharmony_ci if (handle != nullptr) { 4632a6e48fSopenharmony_ci errno_t ret = memset_s(handle, handleSize, 0, handleSize); 4732a6e48fSopenharmony_ci if (ret != 0) { 4832a6e48fSopenharmony_ci UTILS_LOGE("memset_s error, ret is %{public}d", ret); 4932a6e48fSopenharmony_ci free(handle); 5032a6e48fSopenharmony_ci return nullptr; 5132a6e48fSopenharmony_ci } 5232a6e48fSopenharmony_ci handle->fd = -1; 5332a6e48fSopenharmony_ci for (uint32_t i = 0; i < reserveFds; i++) { 5432a6e48fSopenharmony_ci handle->reserve[i] = -1; 5532a6e48fSopenharmony_ci } 5632a6e48fSopenharmony_ci handle->reserveFds = reserveFds; 5732a6e48fSopenharmony_ci handle->reserveInts = reserveInts; 5832a6e48fSopenharmony_ci } else { 5932a6e48fSopenharmony_ci UTILS_LOGE("AllocateBufferHandle malloc %{public}zu failed", handleSize); 6032a6e48fSopenharmony_ci } 6132a6e48fSopenharmony_ci return handle; 6232a6e48fSopenharmony_ci} 6332a6e48fSopenharmony_ci 6432a6e48fSopenharmony_ciint32_t FreeBufferHandle(BufferHandle *handle) 6532a6e48fSopenharmony_ci{ 6632a6e48fSopenharmony_ci if (handle == nullptr) { 6732a6e48fSopenharmony_ci UTILS_LOGW("FreeBufferHandle with nullptr handle"); 6832a6e48fSopenharmony_ci return 0; 6932a6e48fSopenharmony_ci } 7032a6e48fSopenharmony_ci if (handle->fd >= 0) { 7132a6e48fSopenharmony_ci close(handle->fd); 7232a6e48fSopenharmony_ci handle->fd = -1; 7332a6e48fSopenharmony_ci } 7432a6e48fSopenharmony_ci const uint32_t reserveFds = handle->reserveFds; 7532a6e48fSopenharmony_ci for (uint32_t i = 0; i < reserveFds; i++) { 7632a6e48fSopenharmony_ci if (handle->reserve[i] >= 0) { 7732a6e48fSopenharmony_ci close(handle->reserve[i]); 7832a6e48fSopenharmony_ci handle->reserve[i] = -1; 7932a6e48fSopenharmony_ci } 8032a6e48fSopenharmony_ci } 8132a6e48fSopenharmony_ci free(handle); 8232a6e48fSopenharmony_ci return 0; 8332a6e48fSopenharmony_ci} 8432a6e48fSopenharmony_ci 8532a6e48fSopenharmony_cinamespace OHOS { 8632a6e48fSopenharmony_cibool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle) 8732a6e48fSopenharmony_ci{ 8832a6e48fSopenharmony_ci if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) || 8932a6e48fSopenharmony_ci !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) || 9032a6e48fSopenharmony_ci !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) || 9132a6e48fSopenharmony_ci !parcel.WriteUint64(handle.phyAddr)) { 9232a6e48fSopenharmony_ci UTILS_LOGE("%{public}s a lot failed", __func__); 9332a6e48fSopenharmony_ci return false; 9432a6e48fSopenharmony_ci } 9532a6e48fSopenharmony_ci bool validFd = (handle.fd >= 0); 9632a6e48fSopenharmony_ci if (!parcel.WriteBool(validFd)) { 9732a6e48fSopenharmony_ci UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__); 9832a6e48fSopenharmony_ci return false; 9932a6e48fSopenharmony_ci } 10032a6e48fSopenharmony_ci if (validFd && !parcel.WriteFileDescriptor(handle.fd)) { 10132a6e48fSopenharmony_ci UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__); 10232a6e48fSopenharmony_ci return false; 10332a6e48fSopenharmony_ci } 10432a6e48fSopenharmony_ci 10532a6e48fSopenharmony_ci for (uint32_t i = 0; i < handle.reserveFds; i++) { 10632a6e48fSopenharmony_ci if (!parcel.WriteFileDescriptor(handle.reserve[i])) { 10732a6e48fSopenharmony_ci UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__); 10832a6e48fSopenharmony_ci return false; 10932a6e48fSopenharmony_ci } 11032a6e48fSopenharmony_ci } 11132a6e48fSopenharmony_ci for (uint32_t j = 0; j < handle.reserveInts; j++) { 11232a6e48fSopenharmony_ci if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) { 11332a6e48fSopenharmony_ci UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__); 11432a6e48fSopenharmony_ci return false; 11532a6e48fSopenharmony_ci } 11632a6e48fSopenharmony_ci } 11732a6e48fSopenharmony_ci return true; 11832a6e48fSopenharmony_ci} 11932a6e48fSopenharmony_ci 12032a6e48fSopenharmony_ciBufferHandle *ReadBufferHandle(MessageParcel &parcel) 12132a6e48fSopenharmony_ci{ 12232a6e48fSopenharmony_ci uint32_t reserveFds = 0; 12332a6e48fSopenharmony_ci uint32_t reserveInts = 0; 12432a6e48fSopenharmony_ci if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) { 12532a6e48fSopenharmony_ci UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__); 12632a6e48fSopenharmony_ci return nullptr; 12732a6e48fSopenharmony_ci } 12832a6e48fSopenharmony_ci 12932a6e48fSopenharmony_ci BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts); 13032a6e48fSopenharmony_ci if (handle == nullptr) { 13132a6e48fSopenharmony_ci UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__); 13232a6e48fSopenharmony_ci return nullptr; 13332a6e48fSopenharmony_ci } 13432a6e48fSopenharmony_ci 13532a6e48fSopenharmony_ci if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) || 13632a6e48fSopenharmony_ci !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) || 13732a6e48fSopenharmony_ci !parcel.ReadUint64(handle->phyAddr)) { 13832a6e48fSopenharmony_ci UTILS_LOGE("%{public}s a lot failed", __func__); 13932a6e48fSopenharmony_ci FreeBufferHandle(handle); 14032a6e48fSopenharmony_ci return nullptr; 14132a6e48fSopenharmony_ci } 14232a6e48fSopenharmony_ci 14332a6e48fSopenharmony_ci bool validFd = false; 14432a6e48fSopenharmony_ci if (!parcel.ReadBool(validFd)) { 14532a6e48fSopenharmony_ci UTILS_LOGE("%{public}s ReadBool validFd failed", __func__); 14632a6e48fSopenharmony_ci FreeBufferHandle(handle); 14732a6e48fSopenharmony_ci return nullptr; 14832a6e48fSopenharmony_ci } 14932a6e48fSopenharmony_ci if (validFd) { 15032a6e48fSopenharmony_ci handle->fd = parcel.ReadFileDescriptor(); 15132a6e48fSopenharmony_ci if (handle->fd == -1) { 15232a6e48fSopenharmony_ci UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__); 15332a6e48fSopenharmony_ci FreeBufferHandle(handle); 15432a6e48fSopenharmony_ci return nullptr; 15532a6e48fSopenharmony_ci } 15632a6e48fSopenharmony_ci } 15732a6e48fSopenharmony_ci 15832a6e48fSopenharmony_ci for (uint32_t i = 0; i < handle->reserveFds; i++) { 15932a6e48fSopenharmony_ci handle->reserve[i] = parcel.ReadFileDescriptor(); 16032a6e48fSopenharmony_ci if (handle->reserve[i] == -1) { 16132a6e48fSopenharmony_ci UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__); 16232a6e48fSopenharmony_ci FreeBufferHandle(handle); 16332a6e48fSopenharmony_ci return nullptr; 16432a6e48fSopenharmony_ci } 16532a6e48fSopenharmony_ci } 16632a6e48fSopenharmony_ci for (uint32_t j = 0; j < handle->reserveInts; j++) { 16732a6e48fSopenharmony_ci if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) { 16832a6e48fSopenharmony_ci UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__); 16932a6e48fSopenharmony_ci FreeBufferHandle(handle); 17032a6e48fSopenharmony_ci return nullptr; 17132a6e48fSopenharmony_ci } 17232a6e48fSopenharmony_ci } 17332a6e48fSopenharmony_ci return handle; 17432a6e48fSopenharmony_ci} 17532a6e48fSopenharmony_ci} // namespace OHOS 176