1/* 2 * Copyright (c) 2022 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 "surface_tunnel_handle.h" 17#include <securec.h> 18#include "buffer_log.h" 19 20namespace OHOS { 21GraphicExtDataHandle *AllocExtDataHandle(uint32_t reserveInts) 22{ 23 if (static_cast<size_t>(reserveInts) > (SIZE_MAX - sizeof(GraphicExtDataHandle)) / sizeof(int32_t)) { 24 BLOGE("reserveInts: %{public}u is too large", reserveInts); 25 return nullptr; 26 } 27 size_t handleSize = sizeof(GraphicExtDataHandle) + (sizeof(int32_t) * reserveInts); 28 GraphicExtDataHandle *handle = static_cast<GraphicExtDataHandle *>(malloc(handleSize)); 29 if (handle == nullptr) { 30 BLOGE("malloc %{public}zu failed", handleSize); 31 return nullptr; 32 } 33 auto ret = memset_s(handle, handleSize, 0, handleSize); 34 if (ret != EOK) { 35 free(handle); 36 BLOGE("memset_s failed, ret: %{public}d", ret); 37 return nullptr; 38 } 39 handle->fd = -1; 40 handle->reserveInts = reserveInts; 41 for (uint32_t i = 0; i < reserveInts; i++) { 42 handle->reserve[i] = -1; 43 } 44 return handle; 45} 46 47void FreeExtDataHandle(GraphicExtDataHandle *handle) 48{ 49 if (handle == nullptr) { 50 BLOGW("FreeExtDataHandle with nullptr handle"); 51 return; 52 } 53 if (handle->fd >= 0) { 54 close(handle->fd); 55 handle->fd = -1; 56 } 57 free(handle); 58} 59 60SurfaceTunnelHandle::SurfaceTunnelHandle() 61{ 62 BLOGD("SurfaceTunnelHandle ctor"); 63} 64 65SurfaceTunnelHandle::~SurfaceTunnelHandle() 66{ 67 std::lock_guard<std::mutex> lock(mutex_); 68 BLOGD("~SurfaceTunnelHandle dtor tunnelHandle_"); 69 FreeExtDataHandle(tunnelHandle_); 70} 71 72GSError SurfaceTunnelHandle::SetHandle(const GraphicExtDataHandle *handle) 73{ 74 if (handle == nullptr) { // handle is nullptr, which is valid and tunnelHandle_ is nullptr now 75 BLOGW("SetHandle with nullptr"); 76 return GSERROR_OK; 77 } 78 std::lock_guard<std::mutex> lock(mutex_); 79 FreeExtDataHandle(tunnelHandle_); 80 tunnelHandle_ = AllocExtDataHandle(handle->reserveInts); 81 if (tunnelHandle_ == nullptr) { 82 BLOGE("AllocExtDataHandle failed"); 83 return GSERROR_INVALID_OPERATING; 84 } 85 tunnelHandle_->fd = handle->fd; 86 for (uint32_t index = 0; index < handle->reserveInts; index++) { 87 tunnelHandle_->reserve[index] = handle->reserve[index]; 88 } 89 return GSERROR_OK; 90} 91 92GraphicExtDataHandle *SurfaceTunnelHandle::GetHandle() 93{ 94 std::lock_guard<std::mutex> lock(mutex_); 95 return tunnelHandle_; 96} 97 98bool SurfaceTunnelHandle::Different(const sptr<SurfaceTunnelHandle> &handle) 99{ 100 std::lock_guard<std::mutex> lock(mutex_); 101 if (tunnelHandle_ == nullptr) { 102 return false; 103 } 104 if (handle == nullptr || handle->GetHandle() == nullptr) { 105 return true; 106 } 107 108 bool diffHandle = tunnelHandle_->fd != handle->GetHandle()->fd || 109 tunnelHandle_->reserveInts != handle->GetHandle()->reserveInts; 110 if (diffHandle) { 111 return diffHandle; 112 } 113 for (uint32_t index = 0; index < handle->GetHandle()->reserveInts; index++) { 114 diffHandle = diffHandle || tunnelHandle_->reserve[index] != handle->GetHandle()->reserve[index]; 115 } 116 return diffHandle; 117} 118} // namespace OHOS 119