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_utils.h"
17
18 #include <fcntl.h>
19 #include <unistd.h>
20
21 #include "buffer_log.h"
22 #include "surface_buffer_impl.h"
23
24 namespace OHOS {
ReadFileDescriptor(MessageParcel & parcel,int32_t & fd)25 void ReadFileDescriptor(MessageParcel &parcel, int32_t &fd)
26 {
27 fd = parcel.ReadInt32();
28 if (fd < 0) {
29 return;
30 }
31
32 fd = parcel.ReadFileDescriptor();
33 }
34
WriteFileDescriptor(MessageParcel & parcel,int32_t fd)35 void WriteFileDescriptor(MessageParcel &parcel, int32_t fd)
36 {
37 if (fd >= 0 && fcntl(fd, F_GETFL) == -1 && errno == EBADF) {
38 fd = -1;
39 }
40
41 parcel.WriteInt32(fd);
42
43 if (fd < 0) {
44 return;
45 }
46
47 parcel.WriteFileDescriptor(fd);
48 close(fd);
49 }
50
ReadRequestConfig(MessageParcel & parcel,BufferRequestConfig & config)51 void ReadRequestConfig(MessageParcel &parcel, BufferRequestConfig &config)
52 {
53 config.width = parcel.ReadInt32();
54 config.height = parcel.ReadInt32();
55 config.strideAlignment = parcel.ReadInt32();
56 config.format = parcel.ReadInt32();
57 config.usage = parcel.ReadUint64();
58 config.timeout = parcel.ReadInt32();
59 config.colorGamut = static_cast<GraphicColorGamut>(parcel.ReadInt32());
60 config.transform = static_cast<GraphicTransformType>(parcel.ReadInt32());
61 }
62
WriteRequestConfig(MessageParcel & parcel,BufferRequestConfig const & config)63 void WriteRequestConfig(MessageParcel &parcel, BufferRequestConfig const & config)
64 {
65 parcel.WriteInt32(config.width);
66 parcel.WriteInt32(config.height);
67 parcel.WriteInt32(config.strideAlignment);
68 parcel.WriteInt32(config.format);
69 parcel.WriteUint64(config.usage);
70 parcel.WriteInt32(config.timeout);
71 parcel.WriteInt32(static_cast<int32_t>(config.colorGamut));
72 parcel.WriteInt32(static_cast<int32_t>(config.transform));
73 }
74
ReadFlushConfig(MessageParcel & parcel,BufferFlushConfigWithDamages & config)75 void ReadFlushConfig(MessageParcel &parcel, BufferFlushConfigWithDamages &config)
76 {
77 uint32_t size = parcel.ReadUint32();
78 if (size == 0) {
79 BLOGE("The size of damages read from message parcel is 0");
80 return;
81 }
82 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
83 BLOGE("The size of damages read from message parcel exceed the limit");
84 return;
85 }
86 config.damages.clear();
87 config.damages.reserve(size);
88 for (uint32_t i = 0; i < size; i++) {
89 Rect rect = {
90 .x = parcel.ReadInt32(),
91 .y = parcel.ReadInt32(),
92 .w = parcel.ReadInt32(),
93 .h = parcel.ReadInt32(),
94 };
95 config.damages.emplace_back(rect);
96 }
97 config.timestamp = parcel.ReadInt64();
98 }
99
WriteFlushConfig(MessageParcel & parcel,BufferFlushConfigWithDamages const & config)100 void WriteFlushConfig(MessageParcel &parcel, BufferFlushConfigWithDamages const & config)
101 {
102 uint32_t size = config.damages.size();
103 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
104 BLOGE("The size of damages read from message parcel exceed the limit");
105 return;
106 }
107 parcel.WriteUint32(size);
108 for (const auto& rect : config.damages) {
109 parcel.WriteInt32(rect.x);
110 parcel.WriteInt32(rect.y);
111 parcel.WriteInt32(rect.w);
112 parcel.WriteInt32(rect.h);
113 }
114 parcel.WriteInt64(config.timestamp);
115 }
116
ReadSurfaceBufferImpl(MessageParcel & parcel,uint32_t & sequence,sptr<SurfaceBuffer> & buffer)117 GSError ReadSurfaceBufferImpl(MessageParcel &parcel,
118 uint32_t &sequence, sptr<SurfaceBuffer>& buffer)
119 {
120 GSError ret = GSERROR_OK;
121 sequence = parcel.ReadUint32();
122 if (parcel.ReadBool()) {
123 buffer = new SurfaceBufferImpl(sequence);
124 ret = buffer->ReadFromMessageParcel(parcel);
125 }
126 return ret;
127 }
128
WriteSurfaceBufferImpl(MessageParcel & parcel,uint32_t sequence,const sptr<SurfaceBuffer> & buffer)129 void WriteSurfaceBufferImpl(MessageParcel &parcel,
130 uint32_t sequence, const sptr<SurfaceBuffer> &buffer)
131 {
132 parcel.WriteUint32(sequence);
133 parcel.WriteBool(buffer != nullptr);
134 if (buffer == nullptr) {
135 return;
136 }
137 buffer->WriteToMessageParcel(parcel);
138 }
139
ReadVerifyAllocInfo(MessageParcel & parcel,std::vector<BufferVerifyAllocInfo> & infos)140 void ReadVerifyAllocInfo(MessageParcel &parcel, std::vector<BufferVerifyAllocInfo> &infos)
141 {
142 uint32_t size = parcel.ReadUint32();
143 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
144 BLOGE("Too much data obtained from Parcel");
145 return;
146 }
147 infos.clear();
148 BufferVerifyAllocInfo info;
149 for (uint32_t index = 0; index < size; index++) {
150 info.width = parcel.ReadUint32();
151 info.height = parcel.ReadUint32();
152 info.usage = parcel.ReadUint64();
153 info.format = static_cast<GraphicPixelFormat>(parcel.ReadInt32());
154 infos.push_back(info);
155 }
156 }
157
WriteVerifyAllocInfo(MessageParcel & parcel,const std::vector<BufferVerifyAllocInfo> & infos)158 void WriteVerifyAllocInfo(MessageParcel &parcel, const std::vector<BufferVerifyAllocInfo> &infos)
159 {
160 uint32_t size = infos.size();
161 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
162 BLOGE("Too much data obtained from BufferVerifyAllocInfos");
163 return;
164 }
165 parcel.WriteUint32(size);
166 for (const auto &info : infos) {
167 parcel.WriteUint32(info.width);
168 parcel.WriteUint32(info.height);
169 parcel.WriteUint64(info.usage);
170 parcel.WriteInt32(info.format);
171 }
172 }
173
ReadHDRMetaData(MessageParcel & parcel,std::vector<GraphicHDRMetaData> & metaData)174 void ReadHDRMetaData(MessageParcel &parcel, std::vector<GraphicHDRMetaData> &metaData)
175 {
176 uint32_t size = parcel.ReadUint32();
177 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
178 BLOGE("Too much data obtained from Parcel");
179 return;
180 }
181 metaData.clear();
182 GraphicHDRMetaData data;
183 for (uint32_t index = 0; index < size; index++) {
184 data.key = static_cast<GraphicHDRMetadataKey>(parcel.ReadUint32());
185 data.value = parcel.ReadFloat();
186 metaData.push_back(data);
187 }
188 }
189
WriteHDRMetaData(MessageParcel & parcel,const std::vector<GraphicHDRMetaData> & metaData)190 void WriteHDRMetaData(MessageParcel &parcel, const std::vector<GraphicHDRMetaData> &metaData)
191 {
192 uint32_t size = metaData.size();
193 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
194 BLOGE("Too much data obtained from GraphicHDRMetaDatas");
195 return;
196 }
197 parcel.WriteUint32(size);
198 for (const auto &data : metaData) {
199 parcel.WriteUint32(static_cast<uint32_t>(data.key));
200 parcel.WriteFloat(data.value);
201 }
202 }
203
ReadHDRMetaDataSet(MessageParcel & parcel,std::vector<uint8_t> & metaData)204 void ReadHDRMetaDataSet(MessageParcel &parcel, std::vector<uint8_t> &metaData)
205 {
206 uint32_t size = parcel.ReadUint32();
207 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
208 BLOGE("Too much data obtained from Parcel");
209 return;
210 }
211 metaData.clear();
212 for (uint32_t index = 0; index < size; index++) {
213 uint8_t data = parcel.ReadUint8();
214 metaData.push_back(data);
215 }
216 }
217
WriteHDRMetaDataSet(MessageParcel & parcel,const std::vector<uint8_t> & metaData)218 void WriteHDRMetaDataSet(MessageParcel &parcel, const std::vector<uint8_t> &metaData)
219 {
220 uint32_t size = metaData.size();
221 if (size > SURFACE_PARCEL_SIZE_LIMIT) {
222 BLOGE("Too much data obtained from metaDatas");
223 return;
224 }
225 parcel.WriteUint32(size);
226 for (const auto &data : metaData) {
227 parcel.WriteUint8(data);
228 }
229 }
230
ReadExtDataHandle(MessageParcel & parcel,sptr<SurfaceTunnelHandle> & handle)231 void ReadExtDataHandle(MessageParcel &parcel, sptr<SurfaceTunnelHandle> &handle)
232 {
233 if (handle == nullptr) {
234 BLOGE("ReadExtDataHandle failed, handle is null");
235 return;
236 }
237 uint32_t reserveInts = parcel.ReadUint32();
238 if (reserveInts > SURFACE_PARCEL_SIZE_LIMIT) {
239 BLOGE("Too much data obtained from parcel");
240 return;
241 }
242 GraphicExtDataHandle *tunnelHandle = AllocExtDataHandle(reserveInts);
243 if (tunnelHandle == nullptr) {
244 BLOGE("AllocExtDataHandle failed");
245 return;
246 }
247 ReadFileDescriptor(parcel, tunnelHandle->fd);
248 for (uint32_t index = 0; index < reserveInts; index++) {
249 tunnelHandle->reserve[index] = parcel.ReadInt32();
250 }
251 if (handle->SetHandle(tunnelHandle) != GSERROR_OK) {
252 BLOGE("SetHandle failed");
253 return;
254 }
255 FreeExtDataHandle(tunnelHandle);
256 }
257
WriteExtDataHandle(MessageParcel & parcel,const GraphicExtDataHandle * handle)258 void WriteExtDataHandle(MessageParcel &parcel, const GraphicExtDataHandle *handle)
259 {
260 if (handle == nullptr) {
261 BLOGE("WriteExtDataHandle failed, handle is null");
262 return;
263 }
264 uint32_t reserveInts = handle->reserveInts;
265 if (reserveInts > SURFACE_PARCEL_SIZE_LIMIT) {
266 BLOGE("Too much data obtained from reserveInts");
267 return;
268 }
269 parcel.WriteUint32(reserveInts);
270 WriteFileDescriptor(parcel, handle->fd);
271 for (uint32_t index = 0; index < handle->reserveInts; index++) {
272 parcel.WriteInt32(handle->reserve[index]);
273 }
274 }
275 } // namespace OHOS
276