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 #undef LOG_DOMAIN
27 #define LOG_DOMAIN 0xD001400
28 #undef LOG_TAG
29 #define LOG_TAG "graphicutils"
30 #define UTILS_LOGF(...) (void)HILOG_FATAL(LOG_CORE, __VA_ARGS__)
31 #define UTILS_LOGE(...) (void)HILOG_ERROR(LOG_CORE, __VA_ARGS__)
32 #define UTILS_LOGW(...) (void)HILOG_WARN(LOG_CORE, __VA_ARGS__)
33 #define UTILS_LOGI(...) (void)HILOG_INFO(LOG_CORE, __VA_ARGS__)
34 #define UTILS_LOGD(...) (void)HILOG_DEBUG(LOG_CORE, __VA_ARGS__)
35 #define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024
36
AllocateBufferHandle(uint32_t reserveFds,uint32_t reserveInts)37 BufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
38 {
39 if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) {
40 UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager");
41 return nullptr;
42 }
43 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
44 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
45 if (handle != nullptr) {
46 errno_t ret = memset_s(handle, handleSize, 0, handleSize);
47 if (ret != 0) {
48 UTILS_LOGE("memset_s error, ret is %{public}d", ret);
49 free(handle);
50 return nullptr;
51 }
52 handle->fd = -1;
53 for (uint32_t i = 0; i < reserveFds; i++) {
54 handle->reserve[i] = -1;
55 }
56 handle->reserveFds = reserveFds;
57 handle->reserveInts = reserveInts;
58 } else {
59 UTILS_LOGE("InitBufferHandle malloc %zu failed", handleSize);
60 }
61 return handle;
62 }
63
FreeBufferHandle(BufferHandle * handle)64 int32_t FreeBufferHandle(BufferHandle *handle)
65 {
66 if (handle == nullptr) {
67 UTILS_LOGW("FreeBufferHandle with nullptr handle");
68 return 0;
69 }
70 if (handle->fd >= 0) {
71 close(handle->fd);
72 handle->fd = -1;
73 }
74 const uint32_t reserveFds = handle->reserveFds;
75 for (uint32_t i = 0; i < reserveFds; i++) {
76 if (handle->reserve[i] >= 0) {
77 close(handle->reserve[i]);
78 handle->reserve[i] = -1;
79 }
80 }
81 free(handle);
82 return 0;
83 }
84
85 namespace OHOS {
WriteBufferHandle(MessageParcel & parcel,const BufferHandle & handle)86 bool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle)
87 {
88 if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) ||
89 !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) ||
90 !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) ||
91 !parcel.WriteUint64(handle.phyAddr)) {
92 UTILS_LOGE("%{public}s a lot failed", __func__);
93 return false;
94 }
95 bool validFd = (handle.fd >= 0);
96 if (!parcel.WriteBool(validFd)) {
97 UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__);
98 return false;
99 }
100 if (validFd && !parcel.WriteFileDescriptor(handle.fd)) {
101 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__);
102 return false;
103 }
104
105 for (uint32_t i = 0; i < handle.reserveFds; i++) {
106 if (!parcel.WriteFileDescriptor(handle.reserve[i])) {
107 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__);
108 return false;
109 }
110 }
111 for (uint32_t j = 0; j < handle.reserveInts; j++) {
112 if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
113 UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__);
114 return false;
115 }
116 }
117 return true;
118 }
119
ReadBufferHandle(MessageParcel & parcel)120 BufferHandle *ReadBufferHandle(MessageParcel &parcel)
121 {
122 uint32_t reserveFds = 0;
123 uint32_t reserveInts = 0;
124 if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) {
125 UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__);
126 return nullptr;
127 }
128
129 BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts);
130 if (handle == nullptr) {
131 UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__);
132 return nullptr;
133 }
134
135 if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) ||
136 !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) ||
137 !parcel.ReadUint64(handle->phyAddr)) {
138 UTILS_LOGE("%{public}s a lot failed", __func__);
139 FreeBufferHandle(handle);
140 return nullptr;
141 }
142
143 bool validFd = false;
144 if (!parcel.ReadBool(validFd)) {
145 UTILS_LOGE("%{public}s ReadBool validFd failed", __func__);
146 FreeBufferHandle(handle);
147 return nullptr;
148 }
149 if (validFd) {
150 handle->fd = parcel.ReadFileDescriptor();
151 if (handle->fd == -1) {
152 UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__);
153 FreeBufferHandle(handle);
154 return nullptr;
155 }
156 }
157
158 for (uint32_t i = 0; i < handle->reserveFds; i++) {
159 handle->reserve[i] = parcel.ReadFileDescriptor();
160 if (handle->reserve[i] == -1) {
161 UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__);
162 FreeBufferHandle(handle);
163 return nullptr;
164 }
165 }
166 for (uint32_t j = 0; j < handle->reserveInts; j++) {
167 if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) {
168 UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__);
169 FreeBufferHandle(handle);
170 return nullptr;
171 }
172 }
173 return handle;
174 }
175 } // namespace OHOS
176