• 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 
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