1 /*
2 * Copyright (c) 2021 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 "buffer_handle.h"
17 #include "buffer_handle_utils.h"
18
19 #include <cstdlib>
20 #include <securec.h>
21
22 #include <hilog/log.h>
23 #include <message_parcel.h>
24 #include <unistd.h>
25
26 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, 0xD001400, "graphicutils" };
27 #define UTILS_LOGF(...) (void)OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, __VA_ARGS__)
28 #define UTILS_LOGE(...) (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, __VA_ARGS__)
29 #define UTILS_LOGW(...) (void)OHOS::HiviewDFX::HiLog::Warn(LOG_LABEL, __VA_ARGS__)
30 #define UTILS_LOGI(...) (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, __VA_ARGS__)
31 #define UTILS_LOGD(...) (void)OHOS::HiviewDFX::HiLog::Debug(LOG_LABEL, __VA_ARGS__)
32 #define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024
33
AllocateBufferHandle(uint32_t reserveFds,uint32_t reserveInts)34 BufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
35 {
36 if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) {
37 UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager");
38 return nullptr;
39 }
40 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
41 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
42 if (handle != nullptr) {
43 (void)memset_s(handle, handleSize, 0, handleSize);
44 handle->fd = -1;
45 for (uint32_t i = 0; i < reserveFds; i++) {
46 handle->reserve[i] = -1;
47 }
48 handle->reserveFds = reserveFds;
49 handle->reserveInts = reserveInts;
50 } else {
51 UTILS_LOGE("InitBufferHandle malloc %zu failed", handleSize);
52 }
53 return handle;
54 }
55
FreeBufferHandle(BufferHandle * handle)56 int32_t FreeBufferHandle(BufferHandle *handle)
57 {
58 if (handle == nullptr) {
59 UTILS_LOGW("FreeBufferHandle with nullptr handle");
60 return 0;
61 }
62 if (handle->fd >= 0) {
63 close(handle->fd);
64 handle->fd = -1;
65 }
66 const uint32_t reserveFds = handle->reserveFds;
67 for (uint32_t i = 0; i < reserveFds; i++) {
68 if (handle->reserve[i] >= 0) {
69 close(handle->reserve[i]);
70 handle->reserve[i] = -1;
71 }
72 }
73 free(handle);
74 return 0;
75 }
76
CloneBufferHandle(const BufferHandle * handle)77 BufferHandle *CloneBufferHandle(const BufferHandle *handle)
78 {
79 if (handle == nullptr) {
80 UTILS_LOGW("%{public}s handle is nullptr", __func__);
81 return nullptr;
82 }
83
84 BufferHandle *newHandle = AllocateBufferHandle(handle->reserveFds, handle->reserveInts);
85 if (newHandle == nullptr) {
86 UTILS_LOGW("%{public}s AllocateBufferHandle failed, newHandle is nullptr", __func__);
87 return nullptr;
88 }
89
90 if (handle->fd == -1) {
91 newHandle->fd = handle->fd;
92 } else {
93 newHandle->fd = dup(handle->fd);
94 if (newHandle->fd == -1) {
95 UTILS_LOGE("CloneBufferHandle dup failed");
96 FreeBufferHandle(newHandle);
97 return nullptr;
98 }
99 }
100 newHandle->width = handle->width;
101 newHandle->stride = handle->stride;
102 newHandle->height = handle->height;
103 newHandle->size = handle->size;
104 newHandle->format = handle->format;
105 newHandle->usage = handle->usage;
106 newHandle->phyAddr = handle->phyAddr;
107
108 for (uint32_t i = 0; i < newHandle->reserveFds; i++) {
109 newHandle->reserve[i] = dup(handle->reserve[i]);
110 if (newHandle->reserve[i] == -1) {
111 UTILS_LOGE("CloneBufferHandle dup reserveFds failed");
112 FreeBufferHandle(newHandle);
113 return nullptr;
114 }
115 }
116
117 if (handle->reserveInts == 0) {
118 UTILS_LOGD("There is no reserved integer value in old handle, no need to copy");
119 return newHandle;
120 }
121
122 if (memcpy_s(&newHandle->reserve[newHandle->reserveFds], sizeof(int32_t) * newHandle->reserveInts,
123 &handle->reserve[handle->reserveFds], sizeof(int32_t) * handle->reserveInts) != EOK) {
124 UTILS_LOGE("CloneBufferHandle memcpy_s failed");
125 FreeBufferHandle(newHandle);
126 return nullptr;
127 }
128 return newHandle;
129 }
130 namespace OHOS {
WriteBufferHandle(MessageParcel & parcel,const BufferHandle & handle)131 bool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle)
132 {
133 if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) ||
134 !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) ||
135 !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) ||
136 !parcel.WriteUint64(handle.phyAddr)) {
137 UTILS_LOGE("%{public}s a lot failed", __func__);
138 return false;
139 }
140 bool validFd = (handle.fd >= 0);
141 if (!parcel.WriteBool(validFd)) {
142 UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__);
143 return false;
144 }
145 if (validFd && !parcel.WriteFileDescriptor(handle.fd)) {
146 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__);
147 return false;
148 }
149
150 for (uint32_t i = 0; i < handle.reserveFds; i++) {
151 if (!parcel.WriteFileDescriptor(handle.reserve[i])) {
152 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__);
153 return false;
154 }
155 }
156 for (uint32_t j = 0; j < handle.reserveInts; j++) {
157 if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
158 UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__);
159 return false;
160 }
161 }
162 return true;
163 }
164
ReadBufferHandle(MessageParcel & parcel)165 BufferHandle *ReadBufferHandle(MessageParcel &parcel)
166 {
167 uint32_t reserveFds = 0;
168 uint32_t reserveInts = 0;
169 if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) {
170 UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__);
171 return nullptr;
172 }
173
174 BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts);
175 if (handle == nullptr) {
176 UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__);
177 return nullptr;
178 }
179
180 if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) ||
181 !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) ||
182 !parcel.ReadUint64(handle->phyAddr)) {
183 UTILS_LOGE("%{public}s a lot failed", __func__);
184 FreeBufferHandle(handle);
185 return nullptr;
186 }
187
188 bool validFd = false;
189 if (!parcel.ReadBool(validFd)) {
190 UTILS_LOGE("%{public}s ReadBool validFd failed", __func__);
191 FreeBufferHandle(handle);
192 return nullptr;
193 }
194 if (validFd) {
195 handle->fd = parcel.ReadFileDescriptor();
196 if (handle->fd == -1) {
197 UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__);
198 FreeBufferHandle(handle);
199 return nullptr;
200 }
201 }
202
203 for (uint32_t i = 0; i < handle->reserveFds; i++) {
204 handle->reserve[i] = parcel.ReadFileDescriptor();
205 if (handle->reserve[i] == -1) {
206 UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__);
207 FreeBufferHandle(handle);
208 return nullptr;
209 }
210 }
211 for (uint32_t j = 0; j < handle->reserveInts; j++) {
212 if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) {
213 UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__);
214 FreeBufferHandle(handle);
215 return nullptr;
216 }
217 }
218 return handle;
219 }
220 } // namespace OHOS
221