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 <media/stagefright/bqhelper/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 */ 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 */ 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 `binder::Status`. 102 * 103 * \param[in] t The source `Return<void>`. 104 * \return The corresponding `binder::Status`. 105 */ 106 // convert: Return<void> -> ::android::binder::Status 107 ::android::binder::Status toBinderStatus( 108 Return<void> const& t) { 109 return ::android::binder::Status::fromExceptionCode( 110 t.isOk() ? OK : UNKNOWN_ERROR, 111 t.description().c_str()); 112 } 113 114 /** 115 * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls. 116 * 117 * \param[in] t The source `Return<void>`. 118 * \return The corresponding `status_t`. 119 */ 120 // convert: Return<void> -> status_t 121 status_t toStatusT(Return<void> const& t) { 122 return t.isOk() ? OK : UNKNOWN_ERROR; 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 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 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 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> 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> 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 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 = 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 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 + (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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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`. */ 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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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