• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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