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