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
AllocateBufferHandle(uint32_t reserveFds,uint32_t reserveInts)33 BufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
34 {
35 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
36 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
37 if (handle != nullptr) {
38 (void)memset_s(handle, handleSize, 0, handleSize);
39 handle->fd = -1;
40 for (uint32_t i = 0; i < reserveFds; i++) {
41 handle->reserve[i] = -1;
42 }
43 handle->reserveFds = reserveFds;
44 handle->reserveInts = reserveInts;
45 } else {
46 UTILS_LOGE("InitBufferHandle malloc %zu failed", handleSize);
47 }
48 return handle;
49 }
50
FreeBufferHandle(BufferHandle * handle)51 int32_t FreeBufferHandle(BufferHandle *handle)
52 {
53 if (handle == nullptr) {
54 UTILS_LOGW("FreeBufferHandle with nullptr handle");
55 return 0;
56 }
57 if (handle->fd >= 0) {
58 close(handle->fd);
59 handle->fd = -1;
60 }
61 const uint32_t reserveFds = handle->reserveFds;
62 for (uint32_t i = 0; i < reserveFds; i++) {
63 if (handle->reserve[i] >= 0) {
64 close(handle->reserve[i]);
65 handle->reserve[i] = -1;
66 }
67 }
68 free(handle);
69 return 0;
70 }
71
CloneBufferHandle(const BufferHandle * handle)72 BufferHandle *CloneBufferHandle(const BufferHandle *handle)
73 {
74 if (handle == nullptr) {
75 UTILS_LOGW("%{public}s handle is nullptr", __func__);
76 return nullptr;
77 }
78
79 BufferHandle *newHandle = AllocateBufferHandle(handle->reserveFds, handle->reserveInts);
80 if (newHandle == nullptr) {
81 UTILS_LOGW("%{public}s AllocateBufferHandle failed, newHandle is nullptr", __func__);
82 return nullptr;
83 }
84
85 if (handle->fd == -1) {
86 newHandle->fd = handle->fd;
87 } else {
88 newHandle->fd = dup(handle->fd);
89 if (newHandle->fd == -1) {
90 UTILS_LOGE("CloneBufferHandle dup failed");
91 FreeBufferHandle(newHandle);
92 return nullptr;
93 }
94 }
95 newHandle->width = handle->width;
96 newHandle->stride = handle->stride;
97 newHandle->height = handle->height;
98 newHandle->size = handle->size;
99 newHandle->format = handle->format;
100 newHandle->usage = handle->usage;
101 newHandle->phyAddr = handle->phyAddr;
102 newHandle->key = handle->key;
103
104 for (uint32_t i = 0; i < newHandle->reserveFds; i++) {
105 newHandle->reserve[i] = dup(handle->reserve[i]);
106 if (newHandle->reserve[i] == -1) {
107 UTILS_LOGE("CloneBufferHandle dup reserveFds failed");
108 FreeBufferHandle(newHandle);
109 return nullptr;
110 }
111 }
112 if (memcpy_s(&newHandle->reserve[newHandle->reserveFds], sizeof(int32_t) * newHandle->reserveInts,
113 &handle->reserve[handle->reserveFds], sizeof(int32_t) * handle->reserveInts) != EOK) {
114 UTILS_LOGE("CloneBufferHandle memcpy_s failed");
115 FreeBufferHandle(newHandle);
116 return nullptr;
117 }
118 return newHandle;
119 }
120 namespace OHOS {
WriteBufferHandle(MessageParcel & parcel,const BufferHandle & handle)121 bool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle)
122 {
123 if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) ||
124 !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) ||
125 !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) ||
126 !parcel.WriteUint64(handle.phyAddr) || !parcel.WriteInt32(handle.key)) {
127 UTILS_LOGE("%{public}s a lot failed", __func__);
128 return false;
129 }
130 bool validFd = (handle.fd >= 0);
131 if (!parcel.WriteBool(validFd)) {
132 UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__);
133 return false;
134 }
135 if (validFd && !parcel.WriteFileDescriptor(handle.fd)) {
136 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__);
137 return false;
138 }
139
140 for (uint32_t i = 0; i < handle.reserveFds; i++) {
141 if (!parcel.WriteFileDescriptor(handle.reserve[i])) {
142 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__);
143 return false;
144 }
145 }
146 for (uint32_t j = 0; j < handle.reserveInts; j++) {
147 if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
148 UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__);
149 return false;
150 }
151 }
152 return true;
153 }
154
ReadBufferHandle(MessageParcel & parcel)155 BufferHandle *ReadBufferHandle(MessageParcel &parcel)
156 {
157 uint32_t reserveFds = 0;
158 uint32_t reserveInts = 0;
159 if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) {
160 UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__);
161 return nullptr;
162 }
163
164 BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts);
165 if (handle == nullptr) {
166 UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__);
167 return nullptr;
168 }
169
170 if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) ||
171 !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) ||
172 !parcel.ReadUint64(handle->phyAddr) || !parcel.ReadInt32(handle->key)) {
173 UTILS_LOGE("%{public}s a lot failed", __func__);
174 FreeBufferHandle(handle);
175 return nullptr;
176 }
177
178 bool validFd = false;
179 if (!parcel.ReadBool(validFd)) {
180 UTILS_LOGE("%{public}s ReadBool validFd failed", __func__);
181 FreeBufferHandle(handle);
182 return nullptr;
183 }
184 if (validFd) {
185 handle->fd = parcel.ReadFileDescriptor();
186 if (handle->fd == -1) {
187 UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__);
188 FreeBufferHandle(handle);
189 return nullptr;
190 }
191 }
192
193 for (uint32_t i = 0; i < handle->reserveFds; i++) {
194 handle->reserve[i] = parcel.ReadFileDescriptor();
195 if (handle->reserve[i] == -1) {
196 UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__);
197 FreeBufferHandle(handle);
198 return nullptr;
199 }
200 }
201 for (uint32_t j = 0; j < handle->reserveInts; j++) {
202 if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) {
203 UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__);
204 FreeBufferHandle(handle);
205 return nullptr;
206 }
207 }
208 return handle;
209 }
210 } // namespace OHOS
211