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