1 /*
2 * Copyright 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gui/bufferqueue/1.0/Conversion.h>
18
19 namespace android {
20 namespace conversion {
21
22 // native_handle_t helper functions.
23
24 /**
25 * \brief Take an fd and create a native handle containing only the given fd.
26 * The created handle will need to be deleted manually with
27 * `native_handle_delete()`.
28 *
29 * \param[in] fd The source file descriptor (of type `int`).
30 * \return The create `native_handle_t*` that contains the given \p fd. If the
31 * supplied \p fd is negative, the created native handle will contain no file
32 * descriptors.
33 *
34 * If the native handle cannot be created, the return value will be
35 * `nullptr`.
36 *
37 * This function does not duplicate the file descriptor.
38 */
native_handle_create_from_fd(int fd)39 native_handle_t* native_handle_create_from_fd(int fd) {
40 if (fd < 2) {
41 return native_handle_create(0, 0);
42 }
43 native_handle_t* nh = native_handle_create(1, 0);
44 if (nh == nullptr) {
45 return nullptr;
46 }
47 nh->data[0] = fd;
48 return nh;
49 }
50
51 /**
52 * \brief Extract a file descriptor from a native handle.
53 *
54 * \param[in] nh The source `native_handle_t*`.
55 * \param[in] index The index of the file descriptor in \p nh to read from. This
56 * input has the default value of `0`.
57 * \return The `index`-th file descriptor in \p nh. If \p nh does not have
58 * enough file descriptors, the returned value will be `-1`.
59 *
60 * This function does not duplicate the file descriptor.
61 */
native_handle_read_fd(native_handle_t const * nh,int index)62 int native_handle_read_fd(native_handle_t const* nh, int index) {
63 return ((nh == nullptr) || (nh->numFds == 0) ||
64 (nh->numFds <= index) || (index < 0)) ?
65 -1 : nh->data[index];
66 }
67
68 /**
69 * Conversion functions
70 * ====================
71 *
72 * There are two main directions of conversion:
73 * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
74 * input. The wrapper has type `TargetType`.
75 * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
76 * corresponds to the input. The lifetime of the output does not depend on the
77 * lifetime of the input.
78 * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
79 * that cannot be copied and/or moved efficiently, or when there are multiple
80 * output arguments.
81 * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
82 * `TargetType` that cannot be copied and/or moved efficiently, or when there
83 * are multiple output arguments.
84 *
85 * `wrapIn()` and `convertTo()` functions will take output arguments before
86 * input arguments. Some of these functions might return a value to indicate
87 * success or error.
88 *
89 * In converting or wrapping something as a Treble type that contains a
90 * `hidl_handle`, `native_handle_t*` will need to be created and returned as
91 * an additional output argument, hence only `wrapIn()` or `convertTo()` would
92 * be available. The caller must call `native_handle_delete()` to deallocate the
93 * returned native handle when it is no longer needed.
94 *
95 * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
96 * not perform duplication of file descriptors, while `toTargetType()` and
97 * `convertTo()` do.
98 */
99
100 /**
101 * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
102 *
103 * \param[in] t The source `Return<void>`.
104 * \return The corresponding `status_t`.
105 */
106 // convert: Return<void> -> status_t
toStatusT(Return<void> const & t)107 status_t toStatusT(Return<void> const& t) {
108 return t.isOk() ? OK : (t.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR);
109 }
110
111 /**
112 * \brief Convert `Return<void>` to `binder::Status`.
113 *
114 * \param[in] t The source `Return<void>`.
115 * \return The corresponding `binder::Status`.
116 */
117 // convert: Return<void> -> ::android::binder::Status
toBinderStatus(Return<void> const & t)118 ::android::binder::Status toBinderStatus(
119 Return<void> const& t) {
120 return ::android::binder::Status::fromExceptionCode(
121 toStatusT(t),
122 t.description().c_str());
123 }
124
125 /**
126 * \brief Wrap `native_handle_t*` in `hidl_handle`.
127 *
128 * \param[in] nh The source `native_handle_t*`.
129 * \return The `hidl_handle` that points to \p nh.
130 */
131 // wrap: native_handle_t* -> hidl_handle
inHidlHandle(native_handle_t const * nh)132 hidl_handle inHidlHandle(native_handle_t const* nh) {
133 return hidl_handle(nh);
134 }
135
136 /**
137 * \brief Convert `int32_t` to `Dataspace`.
138 *
139 * \param[in] l The source `int32_t`.
140 * \result The corresponding `Dataspace`.
141 */
142 // convert: int32_t -> Dataspace
toHardwareDataspace(int32_t l)143 Dataspace toHardwareDataspace(int32_t l) {
144 return static_cast<Dataspace>(l);
145 }
146
147 /**
148 * \brief Convert `Dataspace` to `int32_t`.
149 *
150 * \param[in] t The source `Dataspace`.
151 * \result The corresponding `int32_t`.
152 */
153 // convert: Dataspace -> int32_t
toRawDataspace(Dataspace const & t)154 int32_t toRawDataspace(Dataspace const& t) {
155 return static_cast<int32_t>(t);
156 }
157
158 /**
159 * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
160 *
161 * \param[in] l The pointer to the beginning of the opaque buffer.
162 * \param[in] size The size of the buffer.
163 * \return A `hidl_vec<uint8_t>` that points to the buffer.
164 */
165 // wrap: void*, size_t -> hidl_vec<uint8_t>
inHidlBytes(void const * l,size_t size)166 hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
167 hidl_vec<uint8_t> t;
168 t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
169 return t;
170 }
171
172 /**
173 * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
174 *
175 * \param[in] l The pointer to the beginning of the opaque buffer.
176 * \param[in] size The size of the buffer.
177 * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
178 */
179 // convert: void*, size_t -> hidl_vec<uint8_t>
toHidlBytes(void const * l,size_t size)180 hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
181 hidl_vec<uint8_t> t;
182 t.resize(size);
183 uint8_t const* src = static_cast<uint8_t const*>(l);
184 std::copy(src, src + size, t.data());
185 return t;
186 }
187
188 /**
189 * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
190 *
191 * \param[out] t The wrapper of type `AnwBuffer`.
192 * \param[in] l The source `GraphicBuffer`.
193 */
194 // wrap: GraphicBuffer -> AnwBuffer
wrapAs(AnwBuffer * t,GraphicBuffer const & l)195 void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
196 t->attr.width = l.getWidth();
197 t->attr.height = l.getHeight();
198 t->attr.stride = l.getStride();
199 t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
200 t->attr.layerCount = l.getLayerCount();
201 t->attr.usage = static_cast<uint32_t>(l.getUsage());
202 t->attr.id = l.getId();
203 t->attr.generationNumber = l.getGenerationNumber();
204 t->nativeHandle = hidl_handle(l.handle);
205 }
206
207 /**
208 * \brief Convert `AnwBuffer` to `GraphicBuffer`.
209 *
210 * \param[out] l The destination `GraphicBuffer`.
211 * \param[in] t The source `AnwBuffer`.
212 *
213 * This function will duplicate all file descriptors in \p t.
214 */
215 // convert: AnwBuffer -> GraphicBuffer
216 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
convertTo(GraphicBuffer * l,AnwBuffer const & t)217 bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
218 native_handle_t* handle = t.nativeHandle == nullptr ?
219 nullptr : native_handle_clone(t.nativeHandle);
220
221 size_t const numInts = 12 + static_cast<size_t>(handle ? handle->numInts : 0);
222 int32_t* ints = new int32_t[numInts];
223
224 size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
225 int* fds = new int[numFds];
226
227 ints[0] = 'GBFR';
228 ints[1] = static_cast<int32_t>(t.attr.width);
229 ints[2] = static_cast<int32_t>(t.attr.height);
230 ints[3] = static_cast<int32_t>(t.attr.stride);
231 ints[4] = static_cast<int32_t>(t.attr.format);
232 ints[5] = static_cast<int32_t>(t.attr.layerCount);
233 ints[6] = static_cast<int32_t>(t.attr.usage);
234 ints[7] = static_cast<int32_t>(t.attr.id >> 32);
235 ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
236 ints[9] = static_cast<int32_t>(t.attr.generationNumber);
237 ints[10] = 0;
238 ints[11] = 0;
239 if (handle) {
240 ints[10] = static_cast<int32_t>(handle->numFds);
241 ints[11] = static_cast<int32_t>(handle->numInts);
242 int* intsStart = handle->data + handle->numFds;
243 std::copy(handle->data, intsStart, fds);
244 std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
245 }
246
247 void const* constBuffer = static_cast<void const*>(ints);
248 size_t size = numInts * sizeof(int32_t);
249 int const* constFds = static_cast<int const*>(fds);
250 status_t status = l->unflatten(constBuffer, size, constFds, numFds);
251
252 delete [] fds;
253 delete [] ints;
254 native_handle_delete(handle);
255 return status == NO_ERROR;
256 }
257
258 /**
259 * Conversion functions for types outside media
260 * ============================================
261 *
262 * Some objects in libui and libgui that were made to go through binder calls do
263 * not expose ways to read or write their fields to the public. To pass an
264 * object of this kind through the HIDL boundary, translation functions need to
265 * work around the access restriction by using the publicly available
266 * `flatten()` and `unflatten()` functions.
267 *
268 * All `flatten()` and `unflatten()` overloads follow the same convention as
269 * follows:
270 *
271 * status_t flatten(ObjectType const& object,
272 * [OtherType const& other, ...]
273 * void*& buffer, size_t& size,
274 * int*& fds, size_t& numFds)
275 *
276 * status_t unflatten(ObjectType* object,
277 * [OtherType* other, ...,]
278 * void*& buffer, size_t& size,
279 * int*& fds, size_t& numFds)
280 *
281 * The number of `other` parameters varies depending on the `ObjectType`. For
282 * example, in the process of unflattening an object that contains
283 * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
284 * be created.
285 *
286 * The last four parameters always work the same way in all overloads of
287 * `flatten()` and `unflatten()`:
288 * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
289 * `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
290 * `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
291 * size (in ints) of the fd buffer pointed to by `fds`.
292 * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
293 * from, `size` is the size (in bytes) of the non-fd buffer pointed to by
294 * `buffer`, `fds` is the pointer to the fd buffer to be read from, and
295 * `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
296 * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
297 * will be advanced, while `size` and `numFds` will be decreased to reflect
298 * how much storage/data of the two buffers (fd and non-fd) have been used.
299 * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
300 * `numFds` are invalid.
301 *
302 * The return value of a successful `flatten()` or `unflatten()` call will be
303 * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
304 *
305 * For each object type that supports flattening, there will be two accompanying
306 * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
307 * return the size of the non-fd buffer that the object will need for
308 * flattening. `getFdCount()` will return the size of the fd buffer that the
309 * object will need for flattening.
310 *
311 * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
312 * `flatten()` and `unflatten()`, are similar to functions of the same name in
313 * the abstract class `Flattenable`. The only difference is that functions in
314 * this file are not member functions of the object type. For example, we write
315 *
316 * flatten(x, buffer, size, fds, numFds)
317 *
318 * instead of
319 *
320 * x.flatten(buffer, size, fds, numFds)
321 *
322 * because we cannot modify the type of `x`.
323 *
324 * There is one exception to the naming convention: `hidl_handle` that
325 * represents a fence. The four functions for this "Fence" type have the word
326 * "Fence" attched to their names because the object type, which is
327 * `hidl_handle`, does not carry the special meaning that the object itself can
328 * only contain zero or one file descriptor.
329 */
330
331 // Ref: frameworks/native/libs/ui/Fence.cpp
332
333 /**
334 * \brief Return the size of the non-fd buffer required to flatten a fence.
335 *
336 * \param[in] fence The input fence of type `hidl_handle`.
337 * \return The required size of the flat buffer.
338 *
339 * The current version of this function always returns 4, which is the number of
340 * bytes required to store the number of file descriptors contained in the fd
341 * part of the flat buffer.
342 */
getFenceFlattenedSize(hidl_handle const &)343 size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
344 return 4;
345 };
346
347 /**
348 * \brief Return the number of file descriptors contained in a fence.
349 *
350 * \param[in] fence The input fence of type `hidl_handle`.
351 * \return `0` if \p fence does not contain a valid file descriptor, or `1`
352 * otherwise.
353 */
getFenceFdCount(hidl_handle const & fence)354 size_t getFenceFdCount(hidl_handle const& fence) {
355 return native_handle_read_fd(fence) == -1 ? 0 : 1;
356 }
357
358 /**
359 * \brief Unflatten `Fence` to `hidl_handle`.
360 *
361 * \param[out] fence The destination `hidl_handle`.
362 * \param[out] nh The underlying native handle.
363 * \param[in,out] buffer The pointer to the flat non-fd buffer.
364 * \param[in,out] size The size of the flat non-fd buffer.
365 * \param[in,out] fds The pointer to the flat fd buffer.
366 * \param[in,out] numFds The size of the flat fd buffer.
367 * \return `NO_ERROR` on success; other value on failure.
368 *
369 * If the return value is `NO_ERROR`, \p nh will point to a newly created
370 * native handle, which needs to be deleted with `native_handle_delete()`
371 * afterwards.
372 */
unflattenFence(hidl_handle * fence,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)373 status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
374 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
375 if (size < 4) {
376 return NO_MEMORY;
377 }
378
379 uint32_t numFdsInHandle;
380 FlattenableUtils::read(buffer, size, numFdsInHandle);
381
382 if (numFdsInHandle > 1) {
383 return BAD_VALUE;
384 }
385
386 if (numFds < numFdsInHandle) {
387 return NO_MEMORY;
388 }
389
390 if (numFdsInHandle) {
391 *nh = native_handle_create_from_fd(*fds);
392 if (*nh == nullptr) {
393 return NO_MEMORY;
394 }
395 *fence = *nh;
396 ++fds;
397 --numFds;
398 } else {
399 *nh = nullptr;
400 *fence = hidl_handle();
401 }
402
403 return NO_ERROR;
404 }
405
406 /**
407 * \brief Flatten `hidl_handle` as `Fence`.
408 *
409 * \param[in] t The source `hidl_handle`.
410 * \param[in,out] buffer The pointer to the flat non-fd buffer.
411 * \param[in,out] size The size of the flat non-fd buffer.
412 * \param[in,out] fds The pointer to the flat fd buffer.
413 * \param[in,out] numFds The size of the flat fd buffer.
414 * \return `NO_ERROR` on success; other value on failure.
415 */
flattenFence(hidl_handle const & fence,void * & buffer,size_t & size,int * & fds,size_t & numFds)416 status_t flattenFence(hidl_handle const& fence,
417 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
418 if (size < getFenceFlattenedSize(fence) ||
419 numFds < getFenceFdCount(fence)) {
420 return NO_MEMORY;
421 }
422 // Cast to uint32_t since the size of a size_t can vary between 32- and
423 // 64-bit processes
424 FlattenableUtils::write(buffer, size,
425 static_cast<uint32_t>(getFenceFdCount(fence)));
426 int fd = native_handle_read_fd(fence);
427 if (fd != -1) {
428 *fds = fd;
429 ++fds;
430 --numFds;
431 }
432 return NO_ERROR;
433 }
434
435 /**
436 * \brief Wrap `Fence` in `hidl_handle`.
437 *
438 * \param[out] t The wrapper of type `hidl_handle`.
439 * \param[out] nh The native handle pointed to by \p t.
440 * \param[in] l The source `Fence`.
441 *
442 * On success, \p nh will hold a newly created native handle, which must be
443 * deleted manually with `native_handle_delete()` afterwards.
444 */
445 // wrap: Fence -> hidl_handle
wrapAs(hidl_handle * t,native_handle_t ** nh,Fence const & l)446 bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
447 size_t const baseSize = l.getFlattenedSize();
448 std::unique_ptr<uint8_t[]> baseBuffer(
449 new (std::nothrow) uint8_t[baseSize]);
450 if (!baseBuffer) {
451 return false;
452 }
453
454 size_t const baseNumFds = l.getFdCount();
455 std::unique_ptr<int[]> baseFds(
456 new (std::nothrow) int[baseNumFds]);
457 if (!baseFds) {
458 return false;
459 }
460
461 void* buffer = static_cast<void*>(baseBuffer.get());
462 size_t size = baseSize;
463 int* fds = static_cast<int*>(baseFds.get());
464 size_t numFds = baseNumFds;
465 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
466 return false;
467 }
468
469 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
470 size = baseSize;
471 int const* constFds = static_cast<int const*>(baseFds.get());
472 numFds = baseNumFds;
473 if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
474 != NO_ERROR) {
475 return false;
476 }
477
478 return true;
479 }
480
481 /**
482 * \brief Convert `hidl_handle` to `Fence`.
483 *
484 * \param[out] l The destination `Fence`. `l` must not have been used
485 * (`l->isValid()` must return `false`) before this function is called.
486 * \param[in] t The source `hidl_handle`.
487 *
488 * If \p t contains a valid file descriptor, it will be duplicated.
489 */
490 // convert: hidl_handle -> Fence
convertTo(Fence * l,hidl_handle const & t)491 bool convertTo(Fence* l, hidl_handle const& t) {
492 int fd = native_handle_read_fd(t);
493 if (fd != -1) {
494 fd = dup(fd);
495 if (fd == -1) {
496 return false;
497 }
498 }
499 native_handle_t* nh = native_handle_create_from_fd(fd);
500 if (nh == nullptr) {
501 if (fd != -1) {
502 close(fd);
503 }
504 return false;
505 }
506
507 size_t const baseSize = getFenceFlattenedSize(t);
508 std::unique_ptr<uint8_t[]> baseBuffer(
509 new (std::nothrow) uint8_t[baseSize]);
510 if (!baseBuffer) {
511 native_handle_delete(nh);
512 return false;
513 }
514
515 size_t const baseNumFds = getFenceFdCount(t);
516 std::unique_ptr<int[]> baseFds(
517 new (std::nothrow) int[baseNumFds]);
518 if (!baseFds) {
519 native_handle_delete(nh);
520 return false;
521 }
522
523 void* buffer = static_cast<void*>(baseBuffer.get());
524 size_t size = baseSize;
525 int* fds = static_cast<int*>(baseFds.get());
526 size_t numFds = baseNumFds;
527 if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
528 native_handle_delete(nh);
529 return false;
530 }
531 native_handle_delete(nh);
532
533 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
534 size = baseSize;
535 int const* constFds = static_cast<int const*>(baseFds.get());
536 numFds = baseNumFds;
537 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
538 return false;
539 }
540
541 return true;
542 }
543
544 // Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
545
546 /**
547 * \brief Return the size of the non-fd buffer required to flatten
548 * `FenceTimeSnapshot`.
549 *
550 * \param[in] t The input `FenceTimeSnapshot`.
551 * \return The required size of the flat buffer.
552 */
getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const & t)553 size_t getFlattenedSize(
554 HGraphicBufferProducer::FenceTimeSnapshot const& t) {
555 constexpr size_t min = sizeof(t.state);
556 switch (t.state) {
557 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
558 return min;
559 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
560 return min + getFenceFlattenedSize(t.fence);
561 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
562 return min + sizeof(
563 ::android::FenceTime::Snapshot::signalTime);
564 }
565 return 0;
566 }
567
568 /**
569 * \brief Return the number of file descriptors contained in
570 * `FenceTimeSnapshot`.
571 *
572 * \param[in] t The input `FenceTimeSnapshot`.
573 * \return The number of file descriptors contained in \p snapshot.
574 */
getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const & t)575 size_t getFdCount(
576 HGraphicBufferProducer::FenceTimeSnapshot const& t) {
577 return t.state ==
578 HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
579 getFenceFdCount(t.fence) : 0;
580 }
581
582 /**
583 * \brief Flatten `FenceTimeSnapshot`.
584 *
585 * \param[in] t The source `FenceTimeSnapshot`.
586 * \param[in,out] buffer The pointer to the flat non-fd buffer.
587 * \param[in,out] size The size of the flat non-fd buffer.
588 * \param[in,out] fds The pointer to the flat fd buffer.
589 * \param[in,out] numFds The size of the flat fd buffer.
590 * \return `NO_ERROR` on success; other value on failure.
591 *
592 * This function will duplicate the file descriptor in `t.fence` if `t.state ==
593 * FENCE`.
594 */
flatten(HGraphicBufferProducer::FenceTimeSnapshot const & t,void * & buffer,size_t & size,int * & fds,size_t & numFds)595 status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
596 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
597 if (size < getFlattenedSize(t)) {
598 return NO_MEMORY;
599 }
600
601 switch (t.state) {
602 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
603 FlattenableUtils::write(buffer, size,
604 ::android::FenceTime::Snapshot::State::EMPTY);
605 return NO_ERROR;
606 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
607 FlattenableUtils::write(buffer, size,
608 ::android::FenceTime::Snapshot::State::FENCE);
609 return flattenFence(t.fence, buffer, size, fds, numFds);
610 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
611 FlattenableUtils::write(buffer, size,
612 ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
613 FlattenableUtils::write(buffer, size, t.signalTimeNs);
614 return NO_ERROR;
615 }
616 return NO_ERROR;
617 }
618
619 /**
620 * \brief Unflatten `FenceTimeSnapshot`.
621 *
622 * \param[out] t The destination `FenceTimeSnapshot`.
623 * \param[out] nh The underlying native handle.
624 * \param[in,out] buffer The pointer to the flat non-fd buffer.
625 * \param[in,out] size The size of the flat non-fd buffer.
626 * \param[in,out] fds The pointer to the flat fd buffer.
627 * \param[in,out] numFds The size of the flat fd buffer.
628 * \return `NO_ERROR` on success; other value on failure.
629 *
630 * If the return value is `NO_ERROR` and the constructed snapshot contains a
631 * file descriptor, \p nh will be created to hold that file descriptor. In this
632 * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
633 */
unflatten(HGraphicBufferProducer::FenceTimeSnapshot * t,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)634 status_t unflatten(
635 HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
636 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
637 if (size < sizeof(t->state)) {
638 return NO_MEMORY;
639 }
640
641 *nh = nullptr;
642 ::android::FenceTime::Snapshot::State state;
643 FlattenableUtils::read(buffer, size, state);
644 switch (state) {
645 case ::android::FenceTime::Snapshot::State::EMPTY:
646 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
647 return NO_ERROR;
648 case ::android::FenceTime::Snapshot::State::FENCE:
649 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
650 return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
651 case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
652 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
653 if (size < sizeof(t->signalTimeNs)) {
654 return NO_MEMORY;
655 }
656 FlattenableUtils::read(buffer, size, t->signalTimeNs);
657 return NO_ERROR;
658 }
659 return NO_ERROR;
660 }
661
662 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
663
664 /**
665 * \brief Return a lower bound on the size of the non-fd buffer required to
666 * flatten `FrameEventsDelta`.
667 *
668 * \param[in] t The input `FrameEventsDelta`.
669 * \return A lower bound on the size of the flat buffer.
670 */
minFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const &)671 constexpr size_t minFlattenedSize(
672 HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
673 return sizeof(uint64_t) + // mFrameNumber
674 sizeof(uint8_t) + // mIndex
675 sizeof(uint8_t) + // mAddPostCompositeCalled
676 sizeof(uint8_t) + // mAddRetireCalled
677 sizeof(uint8_t) + // mAddReleaseCalled
678 sizeof(nsecs_t) + // mPostedTime
679 sizeof(nsecs_t) + // mRequestedPresentTime
680 sizeof(nsecs_t) + // mLatchTime
681 sizeof(nsecs_t) + // mFirstRefreshStartTime
682 sizeof(nsecs_t); // mLastRefreshStartTime
683 }
684
685 /**
686 * \brief Return the size of the non-fd buffer required to flatten
687 * `FrameEventsDelta`.
688 *
689 * \param[in] t The input `FrameEventsDelta`.
690 * \return The required size of the flat buffer.
691 */
getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const & t)692 size_t getFlattenedSize(
693 HGraphicBufferProducer::FrameEventsDelta const& t) {
694 return minFlattenedSize(t) +
695 getFlattenedSize(t.gpuCompositionDoneFence) +
696 getFlattenedSize(t.displayPresentFence) +
697 getFlattenedSize(t.displayRetireFence) +
698 getFlattenedSize(t.releaseFence);
699 };
700
701 /**
702 * \brief Return the number of file descriptors contained in
703 * `FrameEventsDelta`.
704 *
705 * \param[in] t The input `FrameEventsDelta`.
706 * \return The number of file descriptors contained in \p t.
707 */
getFdCount(HGraphicBufferProducer::FrameEventsDelta const & t)708 size_t getFdCount(
709 HGraphicBufferProducer::FrameEventsDelta const& t) {
710 return getFdCount(t.gpuCompositionDoneFence) +
711 getFdCount(t.displayPresentFence) +
712 getFdCount(t.displayRetireFence) +
713 getFdCount(t.releaseFence);
714 };
715
716 /**
717 * \brief Unflatten `FrameEventsDelta`.
718 *
719 * \param[out] t The destination `FrameEventsDelta`.
720 * \param[out] nh The underlying array of native handles.
721 * \param[in,out] buffer The pointer to the flat non-fd buffer.
722 * \param[in,out] size The size of the flat non-fd buffer.
723 * \param[in,out] fds The pointer to the flat fd buffer.
724 * \param[in,out] numFds The size of the flat fd buffer.
725 * \return `NO_ERROR` on success; other value on failure.
726 *
727 * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
728 * populated with `nullptr` or newly created handles. Each non-null slot in \p
729 * nh will need to be deleted manually with `native_handle_delete()`.
730 */
unflatten(HGraphicBufferProducer::FrameEventsDelta * t,std::vector<native_handle_t * > * nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)731 status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
732 std::vector<native_handle_t*>* nh,
733 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
734 if (size < minFlattenedSize(*t)) {
735 return NO_MEMORY;
736 }
737 FlattenableUtils::read(buffer, size, t->frameNumber);
738
739 // These were written as uint8_t for alignment.
740 uint8_t temp = 0;
741 FlattenableUtils::read(buffer, size, temp);
742 size_t index = static_cast<size_t>(temp);
743 if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
744 return BAD_VALUE;
745 }
746 t->index = static_cast<uint32_t>(index);
747
748 FlattenableUtils::read(buffer, size, temp);
749 t->addPostCompositeCalled = static_cast<bool>(temp);
750 FlattenableUtils::read(buffer, size, temp);
751 t->addRetireCalled = static_cast<bool>(temp);
752 FlattenableUtils::read(buffer, size, temp);
753 t->addReleaseCalled = static_cast<bool>(temp);
754
755 FlattenableUtils::read(buffer, size, t->postedTimeNs);
756 FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
757 FlattenableUtils::read(buffer, size, t->latchTimeNs);
758 FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
759 FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
760 FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
761
762 // Fences
763 HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
764 tSnapshot[0] = &t->gpuCompositionDoneFence;
765 tSnapshot[1] = &t->displayPresentFence;
766 tSnapshot[2] = &t->displayRetireFence;
767 tSnapshot[3] = &t->releaseFence;
768 nh->resize(4);
769 for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
770 status_t status = unflatten(
771 tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
772 buffer, size, fds, numFds);
773 if (status != NO_ERROR) {
774 while (snapshotIndex > 0) {
775 --snapshotIndex;
776 if ((*nh)[snapshotIndex] != nullptr) {
777 native_handle_delete((*nh)[snapshotIndex]);
778 }
779 }
780 return status;
781 }
782 }
783 return NO_ERROR;
784 }
785
786 /**
787 * \brief Flatten `FrameEventsDelta`.
788 *
789 * \param[in] t The source `FrameEventsDelta`.
790 * \param[in,out] buffer The pointer to the flat non-fd buffer.
791 * \param[in,out] size The size of the flat non-fd buffer.
792 * \param[in,out] fds The pointer to the flat fd buffer.
793 * \param[in,out] numFds The size of the flat fd buffer.
794 * \return `NO_ERROR` on success; other value on failure.
795 *
796 * This function will duplicate file descriptors contained in \p t.
797 */
798 // Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
799 // FrameEventsDelta::flatten
flatten(HGraphicBufferProducer::FrameEventsDelta const & t,void * & buffer,size_t & size,int * & fds,size_t numFds)800 status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
801 void*& buffer, size_t& size, int*& fds, size_t numFds) {
802 // Check that t.index is within a valid range.
803 if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
804 || t.index > std::numeric_limits<uint8_t>::max()) {
805 return BAD_VALUE;
806 }
807
808 FlattenableUtils::write(buffer, size, t.frameNumber);
809
810 // These are static_cast to uint8_t for alignment.
811 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
812 FlattenableUtils::write(
813 buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
814 FlattenableUtils::write(
815 buffer, size, static_cast<uint8_t>(t.addRetireCalled));
816 FlattenableUtils::write(
817 buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
818
819 FlattenableUtils::write(buffer, size, t.postedTimeNs);
820 FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
821 FlattenableUtils::write(buffer, size, t.latchTimeNs);
822 FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
823 FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
824 FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
825
826 // Fences
827 HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
828 tSnapshot[0] = &t.gpuCompositionDoneFence;
829 tSnapshot[1] = &t.displayPresentFence;
830 tSnapshot[2] = &t.displayRetireFence;
831 tSnapshot[3] = &t.releaseFence;
832 for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
833 status_t status = flatten(
834 *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
835 if (status != NO_ERROR) {
836 return status;
837 }
838 }
839 return NO_ERROR;
840 }
841
842 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
843
844 /**
845 * \brief Return the size of the non-fd buffer required to flatten
846 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
847 *
848 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
849 * \return The required size of the flat buffer.
850 */
getFlattenedSize(HGraphicBufferProducer::FrameEventHistoryDelta const & t)851 size_t getFlattenedSize(
852 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
853 size_t size = 4 + // mDeltas.size()
854 sizeof(t.compositorTiming);
855 for (size_t i = 0; i < t.deltas.size(); ++i) {
856 size += getFlattenedSize(t.deltas[i]);
857 }
858 return size;
859 }
860
861 /**
862 * \brief Return the number of file descriptors contained in
863 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
864 *
865 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
866 * \return The number of file descriptors contained in \p t.
867 */
getFdCount(HGraphicBufferProducer::FrameEventHistoryDelta const & t)868 size_t getFdCount(
869 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
870 size_t numFds = 0;
871 for (size_t i = 0; i < t.deltas.size(); ++i) {
872 numFds += getFdCount(t.deltas[i]);
873 }
874 return numFds;
875 }
876
877 /**
878 * \brief Unflatten `FrameEventHistoryDelta`.
879 *
880 * \param[out] t The destination `FrameEventHistoryDelta`.
881 * \param[out] nh The underlying array of arrays of native handles.
882 * \param[in,out] buffer The pointer to the flat non-fd buffer.
883 * \param[in,out] size The size of the flat non-fd buffer.
884 * \param[in,out] fds The pointer to the flat fd buffer.
885 * \param[in,out] numFds The size of the flat fd buffer.
886 * \return `NO_ERROR` on success; other value on failure.
887 *
888 * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
889 * newly created handles. The second dimension of \p nh will be 4. Each non-null
890 * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
891 */
unflatten(HGraphicBufferProducer::FrameEventHistoryDelta * t,std::vector<std::vector<native_handle_t * >> * nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)892 status_t unflatten(
893 HGraphicBufferProducer::FrameEventHistoryDelta* t,
894 std::vector<std::vector<native_handle_t*> >* nh,
895 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
896 if (size < 4) {
897 return NO_MEMORY;
898 }
899
900 FlattenableUtils::read(buffer, size, t->compositorTiming);
901
902 uint32_t deltaCount = 0;
903 FlattenableUtils::read(buffer, size, deltaCount);
904 if (static_cast<size_t>(deltaCount) >
905 ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
906 return BAD_VALUE;
907 }
908 t->deltas.resize(deltaCount);
909 nh->resize(deltaCount);
910 for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
911 status_t status = unflatten(
912 &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
913 buffer, size, fds, numFds);
914 if (status != NO_ERROR) {
915 return status;
916 }
917 }
918 return NO_ERROR;
919 }
920
921 /**
922 * \brief Flatten `FrameEventHistoryDelta`.
923 *
924 * \param[in] t The source `FrameEventHistoryDelta`.
925 * \param[in,out] buffer The pointer to the flat non-fd buffer.
926 * \param[in,out] size The size of the flat non-fd buffer.
927 * \param[in,out] fds The pointer to the flat fd buffer.
928 * \param[in,out] numFds The size of the flat fd buffer.
929 * \return `NO_ERROR` on success; other value on failure.
930 *
931 * This function will duplicate file descriptors contained in \p t.
932 */
flatten(HGraphicBufferProducer::FrameEventHistoryDelta const & t,void * & buffer,size_t & size,int * & fds,size_t & numFds)933 status_t flatten(
934 HGraphicBufferProducer::FrameEventHistoryDelta const& t,
935 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
936 if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
937 return BAD_VALUE;
938 }
939 if (size < getFlattenedSize(t)) {
940 return NO_MEMORY;
941 }
942
943 FlattenableUtils::write(buffer, size, t.compositorTiming);
944
945 FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
946 for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
947 status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
948 if (status != NO_ERROR) {
949 return status;
950 }
951 }
952 return NO_ERROR;
953 }
954
955 /**
956 * \brief Wrap `::android::FrameEventHistoryData` in
957 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
958 *
959 * \param[out] t The wrapper of type
960 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
961 * \param[out] nh The array of array of native handles that are referred to by
962 * members of \p t.
963 * \param[in] l The source `::android::FrameEventHistoryDelta`.
964 *
965 * On success, each member of \p nh will be either `nullptr` or a newly created
966 * native handle. All the non-`nullptr` elements must be deleted individually
967 * with `native_handle_delete()`.
968 */
wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta * t,std::vector<std::vector<native_handle_t * >> * nh,::android::FrameEventHistoryDelta const & l)969 bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
970 std::vector<std::vector<native_handle_t*> >* nh,
971 ::android::FrameEventHistoryDelta const& l) {
972
973 size_t const baseSize = l.getFlattenedSize();
974 std::unique_ptr<uint8_t[]> baseBuffer(
975 new (std::nothrow) uint8_t[baseSize]);
976 if (!baseBuffer) {
977 return false;
978 }
979
980 size_t const baseNumFds = l.getFdCount();
981 std::unique_ptr<int[]> baseFds(
982 new (std::nothrow) int[baseNumFds]);
983 if (!baseFds) {
984 return false;
985 }
986
987 void* buffer = static_cast<void*>(baseBuffer.get());
988 size_t size = baseSize;
989 int* fds = baseFds.get();
990 size_t numFds = baseNumFds;
991 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
992 return false;
993 }
994
995 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
996 size = baseSize;
997 int const* constFds = static_cast<int const*>(baseFds.get());
998 numFds = baseNumFds;
999 if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
1000 return false;
1001 }
1002
1003 return true;
1004 }
1005
1006 /**
1007 * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
1008 * `::android::FrameEventHistoryDelta`.
1009 *
1010 * \param[out] l The destination `::android::FrameEventHistoryDelta`.
1011 * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
1012 *
1013 * This function will duplicate all file descriptors contained in \p t.
1014 */
convertTo(::android::FrameEventHistoryDelta * l,HGraphicBufferProducer::FrameEventHistoryDelta const & t)1015 bool convertTo(
1016 ::android::FrameEventHistoryDelta* l,
1017 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
1018
1019 size_t const baseSize = getFlattenedSize(t);
1020 std::unique_ptr<uint8_t[]> baseBuffer(
1021 new (std::nothrow) uint8_t[baseSize]);
1022 if (!baseBuffer) {
1023 return false;
1024 }
1025
1026 size_t const baseNumFds = getFdCount(t);
1027 std::unique_ptr<int[]> baseFds(
1028 new (std::nothrow) int[baseNumFds]);
1029 if (!baseFds) {
1030 return false;
1031 }
1032
1033 void* buffer = static_cast<void*>(baseBuffer.get());
1034 size_t size = baseSize;
1035 int* fds = static_cast<int*>(baseFds.get());
1036 size_t numFds = baseNumFds;
1037 if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
1038 return false;
1039 }
1040
1041 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1042 size = baseSize;
1043 int const* constFds = static_cast<int const*>(baseFds.get());
1044 numFds = baseNumFds;
1045 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
1046 return false;
1047 }
1048
1049 return true;
1050 }
1051
1052 // Ref: frameworks/native/libs/ui/Region.cpp
1053
1054 /**
1055 * \brief Return the size of the buffer required to flatten `Region`.
1056 *
1057 * \param[in] t The input `Region`.
1058 * \return The required size of the flat buffer.
1059 */
getFlattenedSize(Region const & t)1060 size_t getFlattenedSize(Region const& t) {
1061 return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
1062 }
1063
1064 /**
1065 * \brief Unflatten `Region`.
1066 *
1067 * \param[out] t The destination `Region`.
1068 * \param[in,out] buffer The pointer to the flat buffer.
1069 * \param[in,out] size The size of the flat buffer.
1070 * \return `NO_ERROR` on success; other value on failure.
1071 */
unflatten(Region * t,void const * & buffer,size_t & size)1072 status_t unflatten(Region* t, void const*& buffer, size_t& size) {
1073 if (size < sizeof(uint32_t)) {
1074 return NO_MEMORY;
1075 }
1076
1077 uint32_t numRects = 0;
1078 FlattenableUtils::read(buffer, size, numRects);
1079 if (size < numRects * sizeof(Rect)) {
1080 return NO_MEMORY;
1081 }
1082 if (numRects > (UINT32_MAX / sizeof(Rect))) {
1083 return NO_MEMORY;
1084 }
1085
1086 t->resize(numRects);
1087 for (size_t r = 0; r < numRects; ++r) {
1088 ::android::Rect rect(::android::Rect::EMPTY_RECT);
1089 status_t status = rect.unflatten(buffer, size);
1090 if (status != NO_ERROR) {
1091 return status;
1092 }
1093 FlattenableUtils::advance(buffer, size, sizeof(rect));
1094 (*t)[r] = Rect{
1095 static_cast<int32_t>(rect.left),
1096 static_cast<int32_t>(rect.top),
1097 static_cast<int32_t>(rect.right),
1098 static_cast<int32_t>(rect.bottom)};
1099 }
1100 return NO_ERROR;
1101 }
1102
1103 /**
1104 * \brief Flatten `Region`.
1105 *
1106 * \param[in] t The source `Region`.
1107 * \param[in,out] buffer The pointer to the flat buffer.
1108 * \param[in,out] size The size of the flat buffer.
1109 * \return `NO_ERROR` on success; other value on failure.
1110 */
flatten(Region const & t,void * & buffer,size_t & size)1111 status_t flatten(Region const& t, void*& buffer, size_t& size) {
1112 if (size < getFlattenedSize(t)) {
1113 return NO_MEMORY;
1114 }
1115
1116 FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
1117 for (size_t r = 0; r < t.size(); ++r) {
1118 ::android::Rect rect(
1119 static_cast<int32_t>(t[r].left),
1120 static_cast<int32_t>(t[r].top),
1121 static_cast<int32_t>(t[r].right),
1122 static_cast<int32_t>(t[r].bottom));
1123 status_t status = rect.flatten(buffer, size);
1124 if (status != NO_ERROR) {
1125 return status;
1126 }
1127 FlattenableUtils::advance(buffer, size, sizeof(rect));
1128 }
1129 return NO_ERROR;
1130 }
1131
1132 /**
1133 * \brief Convert `::android::Region` to `Region`.
1134 *
1135 * \param[out] t The destination `Region`.
1136 * \param[in] l The source `::android::Region`.
1137 */
1138 // convert: ::android::Region -> Region
convertTo(Region * t,::android::Region const & l)1139 bool convertTo(Region* t, ::android::Region const& l) {
1140 size_t const baseSize = l.getFlattenedSize();
1141 std::unique_ptr<uint8_t[]> baseBuffer(
1142 new (std::nothrow) uint8_t[baseSize]);
1143 if (!baseBuffer) {
1144 return false;
1145 }
1146
1147 void* buffer = static_cast<void*>(baseBuffer.get());
1148 size_t size = baseSize;
1149 if (l.flatten(buffer, size) != NO_ERROR) {
1150 return false;
1151 }
1152
1153 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1154 size = baseSize;
1155 if (unflatten(t, constBuffer, size) != NO_ERROR) {
1156 return false;
1157 }
1158
1159 return true;
1160 }
1161
1162 /**
1163 * \brief Convert `Region` to `::android::Region`.
1164 *
1165 * \param[out] l The destination `::android::Region`.
1166 * \param[in] t The source `Region`.
1167 */
1168 // convert: Region -> ::android::Region
convertTo(::android::Region * l,Region const & t)1169 bool convertTo(::android::Region* l, Region const& t) {
1170 size_t const baseSize = getFlattenedSize(t);
1171 std::unique_ptr<uint8_t[]> baseBuffer(
1172 new (std::nothrow) uint8_t[baseSize]);
1173 if (!baseBuffer) {
1174 return false;
1175 }
1176
1177 void* buffer = static_cast<void*>(baseBuffer.get());
1178 size_t size = baseSize;
1179 if (flatten(t, buffer, size) != NO_ERROR) {
1180 return false;
1181 }
1182
1183 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1184 size = baseSize;
1185 if (l->unflatten(constBuffer, size) != NO_ERROR) {
1186 return false;
1187 }
1188
1189 return true;
1190 }
1191
1192 // Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
1193 // BGraphicBufferProducer::QueueBufferInput
1194
1195 /**
1196 * \brief Return a lower bound on the size of the buffer required to flatten
1197 * `HGraphicBufferProducer::QueueBufferInput`.
1198 *
1199 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1200 * \return A lower bound on the size of the flat buffer.
1201 */
minFlattenedSize(HGraphicBufferProducer::QueueBufferInput const &)1202 constexpr size_t minFlattenedSize(
1203 HGraphicBufferProducer::QueueBufferInput const& /* t */) {
1204 return sizeof(int64_t) + // timestamp
1205 sizeof(int) + // isAutoTimestamp
1206 sizeof(android_dataspace) + // dataSpace
1207 sizeof(::android::Rect) + // crop
1208 sizeof(int) + // scalingMode
1209 sizeof(uint32_t) + // transform
1210 sizeof(uint32_t) + // stickyTransform
1211 sizeof(bool); // getFrameTimestamps
1212 }
1213
1214 /**
1215 * \brief Return the size of the buffer required to flatten
1216 * `HGraphicBufferProducer::QueueBufferInput`.
1217 *
1218 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1219 * \return The required size of the flat buffer.
1220 */
getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const & t)1221 size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
1222 return minFlattenedSize(t) +
1223 getFenceFlattenedSize(t.fence) +
1224 getFlattenedSize(t.surfaceDamage) +
1225 sizeof(HdrMetadata::validTypes);
1226 }
1227
1228 /**
1229 * \brief Return the number of file descriptors contained in
1230 * `HGraphicBufferProducer::QueueBufferInput`.
1231 *
1232 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
1233 * \return The number of file descriptors contained in \p t.
1234 */
getFdCount(HGraphicBufferProducer::QueueBufferInput const & t)1235 size_t getFdCount(
1236 HGraphicBufferProducer::QueueBufferInput const& t) {
1237 return getFenceFdCount(t.fence);
1238 }
1239
1240 /**
1241 * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
1242 *
1243 * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
1244 * \param[out] nh The native handle cloned from `t.fence`.
1245 * \param[in,out] buffer The pointer to the flat non-fd buffer.
1246 * \param[in,out] size The size of the flat non-fd buffer.
1247 * \param[in,out] fds The pointer to the flat fd buffer.
1248 * \param[in,out] numFds The size of the flat fd buffer.
1249 * \return `NO_ERROR` on success; other value on failure.
1250 *
1251 * This function will duplicate the file descriptor in `t.fence`. */
flatten(HGraphicBufferProducer::QueueBufferInput const & t,native_handle_t ** nh,void * & buffer,size_t & size,int * & fds,size_t & numFds)1252 status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
1253 native_handle_t** nh,
1254 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
1255 if (size < getFlattenedSize(t)) {
1256 return NO_MEMORY;
1257 }
1258
1259 FlattenableUtils::write(buffer, size, t.timestamp);
1260 FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
1261 FlattenableUtils::write(buffer, size,
1262 static_cast<android_dataspace_t>(t.dataSpace));
1263 FlattenableUtils::write(buffer, size, ::android::Rect(
1264 static_cast<int32_t>(t.crop.left),
1265 static_cast<int32_t>(t.crop.top),
1266 static_cast<int32_t>(t.crop.right),
1267 static_cast<int32_t>(t.crop.bottom)));
1268 FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
1269 FlattenableUtils::write(buffer, size, t.transform);
1270 FlattenableUtils::write(buffer, size, t.stickyTransform);
1271 FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
1272
1273 *nh = t.fence.getNativeHandle() == nullptr ?
1274 nullptr : native_handle_clone(t.fence);
1275 status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
1276 if (status != NO_ERROR) {
1277 return status;
1278 }
1279 status = flatten(t.surfaceDamage, buffer, size);
1280 if (status != NO_ERROR) {
1281 return status;
1282 }
1283 FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
1284 return NO_ERROR;
1285 }
1286
1287 /**
1288 * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
1289 *
1290 * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
1291 * \param[out] nh The underlying native handle for `t->fence`.
1292 * \param[in,out] buffer The pointer to the flat non-fd buffer.
1293 * \param[in,out] size The size of the flat non-fd buffer.
1294 * \param[in,out] fds The pointer to the flat fd buffer.
1295 * \param[in,out] numFds The size of the flat fd buffer.
1296 * \return `NO_ERROR` on success; other value on failure.
1297 *
1298 * If the return value is `NO_ERROR` and `t->fence` contains a valid file
1299 * descriptor, \p nh will be a newly created native handle holding that file
1300 * descriptor. \p nh needs to be deleted with `native_handle_delete()`
1301 * afterwards.
1302 */
unflatten(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)1303 status_t unflatten(
1304 HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
1305 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
1306 if (size < minFlattenedSize(*t)) {
1307 return NO_MEMORY;
1308 }
1309
1310 FlattenableUtils::read(buffer, size, t->timestamp);
1311 int lIsAutoTimestamp;
1312 FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
1313 t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
1314 android_dataspace_t lDataSpace;
1315 FlattenableUtils::read(buffer, size, lDataSpace);
1316 t->dataSpace = static_cast<Dataspace>(lDataSpace);
1317 Rect lCrop;
1318 FlattenableUtils::read(buffer, size, lCrop);
1319 t->crop = Rect{
1320 static_cast<int32_t>(lCrop.left),
1321 static_cast<int32_t>(lCrop.top),
1322 static_cast<int32_t>(lCrop.right),
1323 static_cast<int32_t>(lCrop.bottom)};
1324 int lScalingMode;
1325 FlattenableUtils::read(buffer, size, lScalingMode);
1326 t->scalingMode = static_cast<int32_t>(lScalingMode);
1327 FlattenableUtils::read(buffer, size, t->transform);
1328 FlattenableUtils::read(buffer, size, t->stickyTransform);
1329 FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
1330
1331 status_t status = unflattenFence(&(t->fence), nh,
1332 buffer, size, fds, numFds);
1333 if (status != NO_ERROR) {
1334 return status;
1335 }
1336 // HdrMetadata ignored
1337 return unflatten(&(t->surfaceDamage), buffer, size);
1338 }
1339
1340 /**
1341 * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
1342 * `HGraphicBufferProducer::QueueBufferInput`.
1343 *
1344 * \param[out] t The wrapper of type
1345 * `HGraphicBufferProducer::QueueBufferInput`.
1346 * \param[out] nh The underlying native handle for `t->fence`.
1347 * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
1348 *
1349 * If the return value is `true` and `t->fence` contains a valid file
1350 * descriptor, \p nh will be a newly created native handle holding that file
1351 * descriptor. \p nh needs to be deleted with `native_handle_delete()`
1352 * afterwards.
1353 */
wrapAs(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,BGraphicBufferProducer::QueueBufferInput const & l)1354 bool wrapAs(
1355 HGraphicBufferProducer::QueueBufferInput* t,
1356 native_handle_t** nh,
1357 BGraphicBufferProducer::QueueBufferInput const& l) {
1358
1359 size_t const baseSize = l.getFlattenedSize();
1360 std::unique_ptr<uint8_t[]> baseBuffer(
1361 new (std::nothrow) uint8_t[baseSize]);
1362 if (!baseBuffer) {
1363 return false;
1364 }
1365
1366 size_t const baseNumFds = l.getFdCount();
1367 std::unique_ptr<int[]> baseFds(
1368 new (std::nothrow) int[baseNumFds]);
1369 if (!baseFds) {
1370 return false;
1371 }
1372
1373 void* buffer = static_cast<void*>(baseBuffer.get());
1374 size_t size = baseSize;
1375 int* fds = baseFds.get();
1376 size_t numFds = baseNumFds;
1377 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
1378 return false;
1379 }
1380
1381 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1382 size = baseSize;
1383 int const* constFds = static_cast<int const*>(baseFds.get());
1384 numFds = baseNumFds;
1385 if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
1386 return false;
1387 }
1388
1389 return true;
1390 }
1391
1392 /**
1393 * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
1394 * `BGraphicBufferProducer::QueueBufferInput`.
1395 *
1396 * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
1397 * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
1398 *
1399 * If `t.fence` has a valid file descriptor, it will be duplicated.
1400 */
convertTo(BGraphicBufferProducer::QueueBufferInput * l,HGraphicBufferProducer::QueueBufferInput const & t)1401 bool convertTo(
1402 BGraphicBufferProducer::QueueBufferInput* l,
1403 HGraphicBufferProducer::QueueBufferInput const& t) {
1404
1405 size_t const baseSize = getFlattenedSize(t);
1406 std::unique_ptr<uint8_t[]> baseBuffer(
1407 new (std::nothrow) uint8_t[baseSize]);
1408 if (!baseBuffer) {
1409 return false;
1410 }
1411
1412 size_t const baseNumFds = getFdCount(t);
1413 std::unique_ptr<int[]> baseFds(
1414 new (std::nothrow) int[baseNumFds]);
1415 if (!baseFds) {
1416 return false;
1417 }
1418
1419 void* buffer = static_cast<void*>(baseBuffer.get());
1420 size_t size = baseSize;
1421 int* fds = baseFds.get();
1422 size_t numFds = baseNumFds;
1423 native_handle_t* nh;
1424 if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
1425 return false;
1426 }
1427
1428 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
1429 size = baseSize;
1430 int const* constFds = static_cast<int const*>(baseFds.get());
1431 numFds = baseNumFds;
1432 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
1433 if (nh != nullptr) {
1434 native_handle_close(nh);
1435 native_handle_delete(nh);
1436 }
1437 return false;
1438 }
1439
1440 native_handle_delete(nh);
1441 return true;
1442 }
1443
1444 // Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
1445 // BGraphicBufferProducer::QueueBufferOutput
1446
1447 /**
1448 * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
1449 * `HGraphicBufferProducer::QueueBufferOutput`.
1450 *
1451 * \param[out] t The wrapper of type
1452 * `HGraphicBufferProducer::QueueBufferOutput`.
1453 * \param[out] nh The array of array of native handles that are referred to by
1454 * members of \p t.
1455 * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
1456 *
1457 * On success, each member of \p nh will be either `nullptr` or a newly created
1458 * native handle. All the non-`nullptr` elements must be deleted individually
1459 * with `native_handle_delete()`.
1460 */
1461 // wrap: BGraphicBufferProducer::QueueBufferOutput ->
1462 // HGraphicBufferProducer::QueueBufferOutput
wrapAs(HGraphicBufferProducer::QueueBufferOutput * t,std::vector<std::vector<native_handle_t * >> * nh,BGraphicBufferProducer::QueueBufferOutput const & l)1463 bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
1464 std::vector<std::vector<native_handle_t*> >* nh,
1465 BGraphicBufferProducer::QueueBufferOutput const& l) {
1466 if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
1467 return false;
1468 }
1469 t->width = l.width;
1470 t->height = l.height;
1471 t->transformHint = l.transformHint;
1472 t->numPendingBuffers = l.numPendingBuffers;
1473 t->nextFrameNumber = l.nextFrameNumber;
1474 t->bufferReplaced = l.bufferReplaced;
1475 return true;
1476 }
1477
1478 /**
1479 * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
1480 * `BGraphicBufferProducer::QueueBufferOutput`.
1481 *
1482 * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
1483 * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
1484 *
1485 * This function will duplicate all file descriptors contained in \p t.
1486 */
1487 // convert: HGraphicBufferProducer::QueueBufferOutput ->
1488 // BGraphicBufferProducer::QueueBufferOutput
convertTo(BGraphicBufferProducer::QueueBufferOutput * l,HGraphicBufferProducer::QueueBufferOutput const & t)1489 bool convertTo(
1490 BGraphicBufferProducer::QueueBufferOutput* l,
1491 HGraphicBufferProducer::QueueBufferOutput const& t) {
1492 if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
1493 return false;
1494 }
1495 l->width = t.width;
1496 l->height = t.height;
1497 l->transformHint = t.transformHint;
1498 l->numPendingBuffers = t.numPendingBuffers;
1499 l->nextFrameNumber = t.nextFrameNumber;
1500 l->bufferReplaced = t.bufferReplaced;
1501 return true;
1502 }
1503
1504 /**
1505 * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
1506 * `HGraphicBufferProducer::DisconnectMode`.
1507 *
1508 * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
1509 * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
1510 */
toHidlDisconnectMode(BGraphicBufferProducer::DisconnectMode l)1511 HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
1512 BGraphicBufferProducer::DisconnectMode l) {
1513 switch (l) {
1514 case BGraphicBufferProducer::DisconnectMode::Api:
1515 return HGraphicBufferProducer::DisconnectMode::API;
1516 case BGraphicBufferProducer::DisconnectMode::AllLocal:
1517 return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
1518 }
1519 return HGraphicBufferProducer::DisconnectMode::API;
1520 }
1521
1522 /**
1523 * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
1524 * `BGraphicBufferProducer::DisconnectMode`.
1525 *
1526 * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
1527 * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
1528 */
toGuiDisconnectMode(HGraphicBufferProducer::DisconnectMode t)1529 BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
1530 HGraphicBufferProducer::DisconnectMode t) {
1531 switch (t) {
1532 case HGraphicBufferProducer::DisconnectMode::API:
1533 return BGraphicBufferProducer::DisconnectMode::Api;
1534 case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
1535 return BGraphicBufferProducer::DisconnectMode::AllLocal;
1536 }
1537 return BGraphicBufferProducer::DisconnectMode::Api;
1538 }
1539
1540 } // namespace conversion
1541 } // namespace android
1542
1543