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
20 namespace OHOS {
AllocExtDataHandle(uint32_t reserveInts)21 GraphicExtDataHandle *AllocExtDataHandle(uint32_t reserveInts)
22 {
23 if ((size_t)reserveInts > (SIZE_MAX - sizeof(GraphicExtDataHandle)) / sizeof(int32_t)) {
24 BLOGE("AllocExtDataHandle failed, reserveInts: %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("AllocExtDataHandle malloc %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("AllocExtDataHandle memset_s failed");
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
FreeExtDataHandle(GraphicExtDataHandle * handle)47 void 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
SurfaceTunnelHandle()60 SurfaceTunnelHandle::SurfaceTunnelHandle()
61 {
62 BLOGD("ctor");
63 }
64
~SurfaceTunnelHandle()65 SurfaceTunnelHandle::~SurfaceTunnelHandle()
66 {
67 std::lock_guard<std::mutex> lock(mutex_);
68 BLOGD("dtor tunnelHandle_");
69 FreeExtDataHandle(tunnelHandle_);
70 }
71
SetHandle(const GraphicExtDataHandle * handle)72 GSError SurfaceTunnelHandle::SetHandle(const GraphicExtDataHandle *handle)
73 {
74 std::lock_guard<std::mutex> lock(mutex_);
75 if (tunnelHandle_ != nullptr) {
76 FreeExtDataHandle(tunnelHandle_);
77 tunnelHandle_ = nullptr;
78 }
79 if (handle == nullptr) { // handle is nullptr, which is valid and tunnelHandle_ is nullptr now
80 BLOGW("SetHandle with nullptr");
81 return GSERROR_OK;
82 }
83 tunnelHandle_ = AllocExtDataHandle(handle->reserveInts);
84 if (tunnelHandle_ == nullptr) {
85 BLOGE("SetHandle failed because of AllocExtDataHandle failed");
86 return GSERROR_INVALID_OPERATING;
87 }
88 tunnelHandle_->fd = handle->fd;
89 for (uint32_t index = 0; index < handle->reserveInts; index++) {
90 tunnelHandle_->reserve[index] = handle->reserve[index];
91 }
92 return GSERROR_OK;
93 }
94
GetHandle()95 GraphicExtDataHandle *SurfaceTunnelHandle::GetHandle()
96 {
97 std::lock_guard<std::mutex> lock(mutex_);
98 return tunnelHandle_;
99 }
100
Different(const sptr<SurfaceTunnelHandle> & handle)101 bool SurfaceTunnelHandle::Different(const sptr<SurfaceTunnelHandle> &handle)
102 {
103 std::lock_guard<std::mutex> lock(mutex_);
104 if (tunnelHandle_ == nullptr) {
105 return false;
106 }
107 if (handle == nullptr || handle->GetHandle() == nullptr) {
108 return true;
109 }
110
111 bool diffHandle = tunnelHandle_->fd != handle->GetHandle()->fd ||
112 tunnelHandle_->reserveInts != handle->GetHandle()->reserveInts;
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