1 /* 2 * Copyright (C) 2010 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 <stdint.h> 18 #include <sys/types.h> 19 20 #include <utils/Errors.h> 21 #include <utils/NativeHandle.h> 22 #include <utils/RefBase.h> 23 #include <utils/Timers.h> 24 #include <utils/Vector.h> 25 26 #include <binder/Parcel.h> 27 #include <binder/IInterface.h> 28 29 #include <gui/IGraphicBufferProducer.h> 30 #include <gui/IProducerListener.h> 31 32 namespace android { 33 // ---------------------------------------------------------------------------- 34 35 enum { 36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 37 DEQUEUE_BUFFER, 38 DETACH_BUFFER, 39 DETACH_NEXT_BUFFER, 40 ATTACH_BUFFER, 41 QUEUE_BUFFER, 42 CANCEL_BUFFER, 43 QUERY, 44 CONNECT, 45 DISCONNECT, 46 SET_SIDEBAND_STREAM, 47 ALLOCATE_BUFFERS, 48 ALLOW_ALLOCATION, 49 SET_GENERATION_NUMBER, 50 GET_CONSUMER_NAME, 51 SET_MAX_DEQUEUED_BUFFER_COUNT, 52 SET_ASYNC_MODE, 53 SET_SHARED_BUFFER_MODE, 54 SET_AUTO_REFRESH, 55 SET_DEQUEUE_TIMEOUT, 56 GET_LAST_QUEUED_BUFFER, 57 GET_FRAME_TIMESTAMPS, 58 GET_UNIQUE_ID 59 }; 60 61 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> 62 { 63 public: 64 BpGraphicBufferProducer(const sp<IBinder>& impl) 65 : BpInterface<IGraphicBufferProducer>(impl) 66 { 67 } 68 69 virtual ~BpGraphicBufferProducer(); 70 71 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { 72 Parcel data, reply; 73 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 74 data.writeInt32(bufferIdx); 75 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 76 if (result != NO_ERROR) { 77 return result; 78 } 79 bool nonNull = reply.readInt32(); 80 if (nonNull) { 81 *buf = new GraphicBuffer(); 82 result = reply.read(**buf); 83 if(result != NO_ERROR) { 84 (*buf).clear(); 85 return result; 86 } 87 } 88 result = reply.readInt32(); 89 return result; 90 } 91 92 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) { 93 Parcel data, reply; 94 data.writeInterfaceToken( 95 IGraphicBufferProducer::getInterfaceDescriptor()); 96 data.writeInt32(maxDequeuedBuffers); 97 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT, 98 data, &reply); 99 if (result != NO_ERROR) { 100 return result; 101 } 102 result = reply.readInt32(); 103 return result; 104 } 105 106 virtual status_t setAsyncMode(bool async) { 107 Parcel data, reply; 108 data.writeInterfaceToken( 109 IGraphicBufferProducer::getInterfaceDescriptor()); 110 data.writeInt32(async); 111 status_t result = remote()->transact(SET_ASYNC_MODE, 112 data, &reply); 113 if (result != NO_ERROR) { 114 return result; 115 } 116 result = reply.readInt32(); 117 return result; 118 } 119 120 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width, 121 uint32_t height, PixelFormat format, uint32_t usage) { 122 Parcel data, reply; 123 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 124 data.writeUint32(width); 125 data.writeUint32(height); 126 data.writeInt32(static_cast<int32_t>(format)); 127 data.writeUint32(usage); 128 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); 129 if (result != NO_ERROR) { 130 return result; 131 } 132 *buf = reply.readInt32(); 133 bool nonNull = reply.readInt32(); 134 if (nonNull) { 135 *fence = new Fence(); 136 result = reply.read(**fence); 137 if (result != NO_ERROR) { 138 fence->clear(); 139 return result; 140 } 141 } 142 result = reply.readInt32(); 143 return result; 144 } 145 146 virtual status_t detachBuffer(int slot) { 147 Parcel data, reply; 148 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 149 data.writeInt32(slot); 150 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 151 if (result != NO_ERROR) { 152 return result; 153 } 154 result = reply.readInt32(); 155 return result; 156 } 157 158 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, 159 sp<Fence>* outFence) { 160 if (outBuffer == NULL) { 161 ALOGE("detachNextBuffer: outBuffer must not be NULL"); 162 return BAD_VALUE; 163 } else if (outFence == NULL) { 164 ALOGE("detachNextBuffer: outFence must not be NULL"); 165 return BAD_VALUE; 166 } 167 Parcel data, reply; 168 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 169 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply); 170 if (result != NO_ERROR) { 171 return result; 172 } 173 result = reply.readInt32(); 174 if (result == NO_ERROR) { 175 bool nonNull = reply.readInt32(); 176 if (nonNull) { 177 *outBuffer = new GraphicBuffer; 178 result = reply.read(**outBuffer); 179 if (result != NO_ERROR) { 180 outBuffer->clear(); 181 return result; 182 } 183 } 184 nonNull = reply.readInt32(); 185 if (nonNull) { 186 *outFence = new Fence; 187 result = reply.read(**outFence); 188 if (result != NO_ERROR) { 189 outBuffer->clear(); 190 outFence->clear(); 191 return result; 192 } 193 } 194 } 195 return result; 196 } 197 198 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 199 Parcel data, reply; 200 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 201 data.write(*buffer.get()); 202 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 203 if (result != NO_ERROR) { 204 return result; 205 } 206 *slot = reply.readInt32(); 207 result = reply.readInt32(); 208 return result; 209 } 210 211 virtual status_t queueBuffer(int buf, 212 const QueueBufferInput& input, QueueBufferOutput* output) { 213 Parcel data, reply; 214 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 215 data.writeInt32(buf); 216 data.write(input); 217 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply); 218 if (result != NO_ERROR) { 219 return result; 220 } 221 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 222 result = reply.readInt32(); 223 return result; 224 } 225 226 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) { 227 Parcel data, reply; 228 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 229 data.writeInt32(buf); 230 data.write(*fence.get()); 231 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply); 232 if (result != NO_ERROR) { 233 return result; 234 } 235 result = reply.readInt32(); 236 return result; 237 } 238 239 virtual int query(int what, int* value) { 240 Parcel data, reply; 241 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 242 data.writeInt32(what); 243 status_t result = remote()->transact(QUERY, data, &reply); 244 if (result != NO_ERROR) { 245 return result; 246 } 247 value[0] = reply.readInt32(); 248 result = reply.readInt32(); 249 return result; 250 } 251 252 virtual status_t connect(const sp<IProducerListener>& listener, 253 int api, bool producerControlledByApp, QueueBufferOutput* output) { 254 Parcel data, reply; 255 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 256 if (listener != NULL) { 257 data.writeInt32(1); 258 data.writeStrongBinder(IInterface::asBinder(listener)); 259 } else { 260 data.writeInt32(0); 261 } 262 data.writeInt32(api); 263 data.writeInt32(producerControlledByApp); 264 status_t result = remote()->transact(CONNECT, data, &reply); 265 if (result != NO_ERROR) { 266 return result; 267 } 268 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 269 result = reply.readInt32(); 270 return result; 271 } 272 273 virtual status_t disconnect(int api, DisconnectMode mode) { 274 Parcel data, reply; 275 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 276 data.writeInt32(api); 277 data.writeInt32(static_cast<int32_t>(mode)); 278 status_t result =remote()->transact(DISCONNECT, data, &reply); 279 if (result != NO_ERROR) { 280 return result; 281 } 282 result = reply.readInt32(); 283 return result; 284 } 285 286 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) { 287 Parcel data, reply; 288 status_t result; 289 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 290 if (stream.get()) { 291 data.writeInt32(true); 292 data.writeNativeHandle(stream->handle()); 293 } else { 294 data.writeInt32(false); 295 } 296 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) { 297 result = reply.readInt32(); 298 } 299 return result; 300 } 301 302 virtual void allocateBuffers(uint32_t width, uint32_t height, 303 PixelFormat format, uint32_t usage) { 304 Parcel data, reply; 305 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 306 data.writeUint32(width); 307 data.writeUint32(height); 308 data.writeInt32(static_cast<int32_t>(format)); 309 data.writeUint32(usage); 310 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); 311 if (result != NO_ERROR) { 312 ALOGE("allocateBuffers failed to transact: %d", result); 313 } 314 } 315 316 virtual status_t allowAllocation(bool allow) { 317 Parcel data, reply; 318 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 319 data.writeInt32(static_cast<int32_t>(allow)); 320 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply); 321 if (result != NO_ERROR) { 322 return result; 323 } 324 result = reply.readInt32(); 325 return result; 326 } 327 328 virtual status_t setGenerationNumber(uint32_t generationNumber) { 329 Parcel data, reply; 330 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 331 data.writeUint32(generationNumber); 332 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply); 333 if (result == NO_ERROR) { 334 result = reply.readInt32(); 335 } 336 return result; 337 } 338 339 virtual String8 getConsumerName() const { 340 Parcel data, reply; 341 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 342 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply); 343 if (result != NO_ERROR) { 344 ALOGE("getConsumerName failed to transact: %d", result); 345 return String8("TransactFailed"); 346 } 347 return reply.readString8(); 348 } 349 350 virtual status_t setSharedBufferMode(bool sharedBufferMode) { 351 Parcel data, reply; 352 data.writeInterfaceToken( 353 IGraphicBufferProducer::getInterfaceDescriptor()); 354 data.writeInt32(sharedBufferMode); 355 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data, 356 &reply); 357 if (result == NO_ERROR) { 358 result = reply.readInt32(); 359 } 360 return result; 361 } 362 363 virtual status_t setAutoRefresh(bool autoRefresh) { 364 Parcel data, reply; 365 data.writeInterfaceToken( 366 IGraphicBufferProducer::getInterfaceDescriptor()); 367 data.writeInt32(autoRefresh); 368 status_t result = remote()->transact(SET_AUTO_REFRESH, data, &reply); 369 if (result == NO_ERROR) { 370 result = reply.readInt32(); 371 } 372 return result; 373 } 374 375 virtual status_t setDequeueTimeout(nsecs_t timeout) { 376 Parcel data, reply; 377 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 378 data.writeInt64(timeout); 379 status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply); 380 if (result != NO_ERROR) { 381 ALOGE("setDequeueTimeout failed to transact: %d", result); 382 return result; 383 } 384 return reply.readInt32(); 385 } 386 387 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 388 sp<Fence>* outFence, float outTransformMatrix[16]) override { 389 Parcel data, reply; 390 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 391 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data, 392 &reply); 393 if (result != NO_ERROR) { 394 ALOGE("getLastQueuedBuffer failed to transact: %d", result); 395 return result; 396 } 397 result = reply.readInt32(); 398 if (result != NO_ERROR) { 399 return result; 400 } 401 bool hasBuffer = reply.readBool(); 402 sp<GraphicBuffer> buffer; 403 if (hasBuffer) { 404 buffer = new GraphicBuffer(); 405 result = reply.read(*buffer); 406 if (result == NO_ERROR) { 407 result = reply.read(outTransformMatrix, sizeof(float) * 16); 408 } 409 } 410 if (result != NO_ERROR) { 411 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result); 412 return result; 413 } 414 sp<Fence> fence(new Fence); 415 result = reply.read(*fence); 416 if (result != NO_ERROR) { 417 ALOGE("getLastQueuedBuffer failed to read fence: %d", result); 418 return result; 419 } 420 *outBuffer = buffer; 421 *outFence = fence; 422 return result; 423 } 424 425 virtual bool getFrameTimestamps(uint64_t frameNumber, 426 FrameTimestamps* outTimestamps) const { 427 Parcel data, reply; 428 status_t result = data.writeInterfaceToken( 429 IGraphicBufferProducer::getInterfaceDescriptor()); 430 if (result != NO_ERROR) { 431 ALOGE("getFrameTimestamps failed to write token: %d", result); 432 return false; 433 } 434 result = data.writeUint64(frameNumber); 435 if (result != NO_ERROR) { 436 ALOGE("getFrameTimestamps failed to write: %d", result); 437 return false; 438 } 439 result = remote()->transact(GET_FRAME_TIMESTAMPS, data, &reply); 440 if (result != NO_ERROR) { 441 ALOGE("getFrameTimestamps failed to transact: %d", result); 442 return false; 443 } 444 bool found = false; 445 result = reply.readBool(&found); 446 if (result != NO_ERROR) { 447 ALOGE("getFrameTimestamps failed to read: %d", result); 448 return false; 449 } 450 if (found) { 451 result = reply.read(*outTimestamps); 452 if (result != NO_ERROR) { 453 ALOGE("getFrameTimestamps failed to read timestamps: %d", 454 result); 455 return false; 456 } 457 } 458 return found; 459 } 460 461 virtual status_t getUniqueId(uint64_t* outId) const { 462 Parcel data, reply; 463 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 464 status_t result = remote()->transact(GET_UNIQUE_ID, data, &reply); 465 if (result != NO_ERROR) { 466 ALOGE("getUniqueId failed to transact: %d", result); 467 } 468 status_t actualResult = NO_ERROR; 469 result = reply.readInt32(&actualResult); 470 if (result != NO_ERROR) { 471 return result; 472 } 473 result = reply.readUint64(outId); 474 if (result != NO_ERROR) { 475 return result; 476 } 477 return actualResult; 478 } 479 }; 480 481 // Out-of-line virtual method definition to trigger vtable emission in this 482 // translation unit (see clang warning -Wweak-vtables) 483 BpGraphicBufferProducer::~BpGraphicBufferProducer() {} 484 485 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer"); 486 487 // ---------------------------------------------------------------------- 488 489 status_t BnGraphicBufferProducer::onTransact( 490 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 491 { 492 switch(code) { 493 case REQUEST_BUFFER: { 494 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 495 int bufferIdx = data.readInt32(); 496 sp<GraphicBuffer> buffer; 497 int result = requestBuffer(bufferIdx, &buffer); 498 reply->writeInt32(buffer != 0); 499 if (buffer != 0) { 500 reply->write(*buffer); 501 } 502 reply->writeInt32(result); 503 return NO_ERROR; 504 } 505 case SET_MAX_DEQUEUED_BUFFER_COUNT: { 506 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 507 int maxDequeuedBuffers = data.readInt32(); 508 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers); 509 reply->writeInt32(result); 510 return NO_ERROR; 511 } 512 case SET_ASYNC_MODE: { 513 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 514 bool async = data.readInt32(); 515 int result = setAsyncMode(async); 516 reply->writeInt32(result); 517 return NO_ERROR; 518 } 519 case DEQUEUE_BUFFER: { 520 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 521 uint32_t width = data.readUint32(); 522 uint32_t height = data.readUint32(); 523 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 524 uint32_t usage = data.readUint32(); 525 int buf = 0; 526 sp<Fence> fence; 527 int result = dequeueBuffer(&buf, &fence, width, height, format, 528 usage); 529 reply->writeInt32(buf); 530 reply->writeInt32(fence != NULL); 531 if (fence != NULL) { 532 reply->write(*fence); 533 } 534 reply->writeInt32(result); 535 return NO_ERROR; 536 } 537 case DETACH_BUFFER: { 538 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 539 int slot = data.readInt32(); 540 int result = detachBuffer(slot); 541 reply->writeInt32(result); 542 return NO_ERROR; 543 } 544 case DETACH_NEXT_BUFFER: { 545 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 546 sp<GraphicBuffer> buffer; 547 sp<Fence> fence; 548 int32_t result = detachNextBuffer(&buffer, &fence); 549 reply->writeInt32(result); 550 if (result == NO_ERROR) { 551 reply->writeInt32(buffer != NULL); 552 if (buffer != NULL) { 553 reply->write(*buffer); 554 } 555 reply->writeInt32(fence != NULL); 556 if (fence != NULL) { 557 reply->write(*fence); 558 } 559 } 560 return NO_ERROR; 561 } 562 case ATTACH_BUFFER: { 563 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 564 sp<GraphicBuffer> buffer = new GraphicBuffer(); 565 status_t result = data.read(*buffer.get()); 566 int slot = 0; 567 if (result == NO_ERROR) { 568 result = attachBuffer(&slot, buffer); 569 } 570 reply->writeInt32(slot); 571 reply->writeInt32(result); 572 return NO_ERROR; 573 } 574 case QUEUE_BUFFER: { 575 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 576 int buf = data.readInt32(); 577 QueueBufferInput input(data); 578 QueueBufferOutput* const output = 579 reinterpret_cast<QueueBufferOutput *>( 580 reply->writeInplace(sizeof(QueueBufferOutput))); 581 memset(output, 0, sizeof(QueueBufferOutput)); 582 status_t result = queueBuffer(buf, input, output); 583 reply->writeInt32(result); 584 return NO_ERROR; 585 } 586 case CANCEL_BUFFER: { 587 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 588 int buf = data.readInt32(); 589 sp<Fence> fence = new Fence(); 590 status_t result = data.read(*fence.get()); 591 if (result == NO_ERROR) { 592 result = cancelBuffer(buf, fence); 593 } 594 reply->writeInt32(result); 595 return NO_ERROR; 596 } 597 case QUERY: { 598 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 599 int value = 0; 600 int what = data.readInt32(); 601 int res = query(what, &value); 602 reply->writeInt32(value); 603 reply->writeInt32(res); 604 return NO_ERROR; 605 } 606 case CONNECT: { 607 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 608 sp<IProducerListener> listener; 609 if (data.readInt32() == 1) { 610 listener = IProducerListener::asInterface(data.readStrongBinder()); 611 } 612 int api = data.readInt32(); 613 bool producerControlledByApp = data.readInt32(); 614 QueueBufferOutput* const output = 615 reinterpret_cast<QueueBufferOutput *>( 616 reply->writeInplace(sizeof(QueueBufferOutput))); 617 memset(output, 0, sizeof(QueueBufferOutput)); 618 status_t res = connect(listener, api, producerControlledByApp, output); 619 reply->writeInt32(res); 620 return NO_ERROR; 621 } 622 case DISCONNECT: { 623 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 624 int api = data.readInt32(); 625 DisconnectMode mode = static_cast<DisconnectMode>(data.readInt32()); 626 status_t res = disconnect(api, mode); 627 reply->writeInt32(res); 628 return NO_ERROR; 629 } 630 case SET_SIDEBAND_STREAM: { 631 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 632 sp<NativeHandle> stream; 633 if (data.readInt32()) { 634 stream = NativeHandle::create(data.readNativeHandle(), true); 635 } 636 status_t result = setSidebandStream(stream); 637 reply->writeInt32(result); 638 return NO_ERROR; 639 } 640 case ALLOCATE_BUFFERS: { 641 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 642 uint32_t width = data.readUint32(); 643 uint32_t height = data.readUint32(); 644 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 645 uint32_t usage = data.readUint32(); 646 allocateBuffers(width, height, format, usage); 647 return NO_ERROR; 648 } 649 case ALLOW_ALLOCATION: { 650 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 651 bool allow = static_cast<bool>(data.readInt32()); 652 status_t result = allowAllocation(allow); 653 reply->writeInt32(result); 654 return NO_ERROR; 655 } 656 case SET_GENERATION_NUMBER: { 657 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 658 uint32_t generationNumber = data.readUint32(); 659 status_t result = setGenerationNumber(generationNumber); 660 reply->writeInt32(result); 661 return NO_ERROR; 662 } 663 case GET_CONSUMER_NAME: { 664 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 665 reply->writeString8(getConsumerName()); 666 return NO_ERROR; 667 } 668 case SET_SHARED_BUFFER_MODE: { 669 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 670 bool sharedBufferMode = data.readInt32(); 671 status_t result = setSharedBufferMode(sharedBufferMode); 672 reply->writeInt32(result); 673 return NO_ERROR; 674 } 675 case SET_AUTO_REFRESH: { 676 CHECK_INTERFACE(IGraphicBuffer, data, reply); 677 bool autoRefresh = data.readInt32(); 678 status_t result = setAutoRefresh(autoRefresh); 679 reply->writeInt32(result); 680 return NO_ERROR; 681 } 682 case SET_DEQUEUE_TIMEOUT: { 683 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 684 nsecs_t timeout = data.readInt64(); 685 status_t result = setDequeueTimeout(timeout); 686 reply->writeInt32(result); 687 return NO_ERROR; 688 } 689 case GET_LAST_QUEUED_BUFFER: { 690 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 691 sp<GraphicBuffer> buffer(nullptr); 692 sp<Fence> fence(Fence::NO_FENCE); 693 float transform[16] = {}; 694 status_t result = getLastQueuedBuffer(&buffer, &fence, transform); 695 reply->writeInt32(result); 696 if (result != NO_ERROR) { 697 return result; 698 } 699 if (!buffer.get()) { 700 reply->writeBool(false); 701 } else { 702 reply->writeBool(true); 703 result = reply->write(*buffer); 704 if (result == NO_ERROR) { 705 reply->write(transform, sizeof(float) * 16); 706 } 707 } 708 if (result != NO_ERROR) { 709 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result); 710 return result; 711 } 712 result = reply->write(*fence); 713 if (result != NO_ERROR) { 714 ALOGE("getLastQueuedBuffer failed to write fence: %d", result); 715 return result; 716 } 717 return NO_ERROR; 718 } 719 case GET_FRAME_TIMESTAMPS: { 720 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 721 uint64_t frameNumber = 0; 722 status_t result = data.readUint64(&frameNumber); 723 if (result != NO_ERROR) { 724 ALOGE("onTransact failed to read: %d", result); 725 return result; 726 } 727 FrameTimestamps timestamps; 728 bool found = getFrameTimestamps(frameNumber, ×tamps); 729 result = reply->writeBool(found); 730 if (result != NO_ERROR) { 731 ALOGE("onTransact failed to write: %d", result); 732 return result; 733 } 734 if (found) { 735 result = reply->write(timestamps); 736 if (result != NO_ERROR) { 737 ALOGE("onTransact failed to write timestamps: %d", result); 738 return result; 739 } 740 } 741 return NO_ERROR; 742 } 743 case GET_UNIQUE_ID: { 744 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 745 uint64_t outId = 0; 746 status_t actualResult = getUniqueId(&outId); 747 status_t result = reply->writeInt32(actualResult); 748 if (result != NO_ERROR) { 749 return result; 750 } 751 result = reply->writeUint64(outId); 752 if (result != NO_ERROR) { 753 return result; 754 } 755 return NO_ERROR; 756 } 757 } 758 return BBinder::onTransact(code, data, reply, flags); 759 } 760 761 // ---------------------------------------------------------------------------- 762 763 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { 764 parcel.read(*this); 765 } 766 767 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { 768 return sizeof(timestamp) 769 + sizeof(isAutoTimestamp) 770 + sizeof(dataSpace) 771 + sizeof(crop) 772 + sizeof(scalingMode) 773 + sizeof(transform) 774 + sizeof(stickyTransform) 775 + fence->getFlattenedSize() 776 + surfaceDamage.getFlattenedSize(); 777 } 778 779 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { 780 return fence->getFdCount(); 781 } 782 783 status_t IGraphicBufferProducer::QueueBufferInput::flatten( 784 void*& buffer, size_t& size, int*& fds, size_t& count) const 785 { 786 if (size < getFlattenedSize()) { 787 return NO_MEMORY; 788 } 789 FlattenableUtils::write(buffer, size, timestamp); 790 FlattenableUtils::write(buffer, size, isAutoTimestamp); 791 FlattenableUtils::write(buffer, size, dataSpace); 792 FlattenableUtils::write(buffer, size, crop); 793 FlattenableUtils::write(buffer, size, scalingMode); 794 FlattenableUtils::write(buffer, size, transform); 795 FlattenableUtils::write(buffer, size, stickyTransform); 796 status_t result = fence->flatten(buffer, size, fds, count); 797 if (result != NO_ERROR) { 798 return result; 799 } 800 return surfaceDamage.flatten(buffer, size); 801 } 802 803 status_t IGraphicBufferProducer::QueueBufferInput::unflatten( 804 void const*& buffer, size_t& size, int const*& fds, size_t& count) 805 { 806 size_t minNeeded = 807 sizeof(timestamp) 808 + sizeof(isAutoTimestamp) 809 + sizeof(dataSpace) 810 + sizeof(crop) 811 + sizeof(scalingMode) 812 + sizeof(transform) 813 + sizeof(stickyTransform); 814 815 if (size < minNeeded) { 816 return NO_MEMORY; 817 } 818 819 FlattenableUtils::read(buffer, size, timestamp); 820 FlattenableUtils::read(buffer, size, isAutoTimestamp); 821 FlattenableUtils::read(buffer, size, dataSpace); 822 FlattenableUtils::read(buffer, size, crop); 823 FlattenableUtils::read(buffer, size, scalingMode); 824 FlattenableUtils::read(buffer, size, transform); 825 FlattenableUtils::read(buffer, size, stickyTransform); 826 827 fence = new Fence(); 828 status_t result = fence->unflatten(buffer, size, fds, count); 829 if (result != NO_ERROR) { 830 return result; 831 } 832 return surfaceDamage.unflatten(buffer, size); 833 } 834 835 }; // namespace android 836