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("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("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("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
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("SurfaceTunnelHandle ctor");
63 }
64
~SurfaceTunnelHandle()65 SurfaceTunnelHandle::~SurfaceTunnelHandle()
66 {
67 std::lock_guard<std::mutex> lock(mutex_);
68 BLOGD("~SurfaceTunnelHandle dtor tunnelHandle_");
69 FreeExtDataHandle(tunnelHandle_);
70 }
71
SetHandle(const GraphicExtDataHandle * handle)72 GSError 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
GetHandle()92 GraphicExtDataHandle *SurfaceTunnelHandle::GetHandle()
93 {
94 std::lock_guard<std::mutex> lock(mutex_);
95 return tunnelHandle_;
96 }
97
Different(const sptr<SurfaceTunnelHandle> & handle)98 bool 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