1 /* 2 * Copyright (c) 2009 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "IOMX" 19 #include <utils/Log.h> 20 21 #include <sys/mman.h> 22 23 #include <binder/IMemory.h> 24 #include <binder/Parcel.h> 25 #include <media/IOMX.h> 26 #include <media/stagefright/foundation/ADebug.h> 27 #include <media/openmax/OMX_IndexExt.h> 28 #include <media/OMXBuffer.h> 29 #include <utils/NativeHandle.h> 30 31 #include <media/omx/1.0/WOmxNode.h> 32 #include <android/IGraphicBufferSource.h> 33 #include <android/IOMXBufferSource.h> 34 35 namespace android { 36 37 enum { 38 CONNECT = IBinder::FIRST_CALL_TRANSACTION, 39 LIST_NODES, 40 ALLOCATE_NODE, 41 CREATE_INPUT_SURFACE, 42 FREE_NODE, 43 SEND_COMMAND, 44 GET_PARAMETER, 45 SET_PARAMETER, 46 GET_CONFIG, 47 SET_CONFIG, 48 SET_PORT_MODE, 49 SET_INPUT_SURFACE, 50 PREPARE_FOR_ADAPTIVE_PLAYBACK, 51 ALLOC_SECURE_BUFFER, 52 USE_BUFFER, 53 FREE_BUFFER, 54 FILL_BUFFER, 55 EMPTY_BUFFER, 56 GET_EXTENSION_INDEX, 57 OBSERVER_ON_MSG, 58 GET_GRAPHIC_BUFFER_USAGE, 59 CONFIGURE_VIDEO_TUNNEL_MODE, 60 DISPATCH_MESSAGE, 61 SET_QUIRKS, 62 }; 63 64 class BpOMXNode : public BpInterface<IOMXNode> { 65 public: 66 explicit BpOMXNode(const sp<IBinder> &impl) 67 : BpInterface<IOMXNode>(impl) { 68 } 69 70 virtual status_t freeNode() { 71 Parcel data, reply; 72 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 73 remote()->transact(FREE_NODE, data, &reply); 74 75 return reply.readInt32(); 76 } 77 78 virtual status_t sendCommand( 79 OMX_COMMANDTYPE cmd, OMX_S32 param) { 80 Parcel data, reply; 81 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 82 data.writeInt32(cmd); 83 data.writeInt32(param); 84 remote()->transact(SEND_COMMAND, data, &reply); 85 86 return reply.readInt32(); 87 } 88 89 virtual status_t getParameter( 90 OMX_INDEXTYPE index, 91 void *params, size_t size) { 92 Parcel data, reply; 93 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 94 data.writeInt32(index); 95 data.writeInt64(size); 96 data.write(params, size); 97 remote()->transact(GET_PARAMETER, data, &reply); 98 99 status_t err = reply.readInt32(); 100 if (err != OK) { 101 return err; 102 } 103 104 reply.read(params, size); 105 106 return OK; 107 } 108 109 virtual status_t setParameter( 110 OMX_INDEXTYPE index, 111 const void *params, size_t size) { 112 Parcel data, reply; 113 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 114 data.writeInt32(index); 115 data.writeInt64(size); 116 data.write(params, size); 117 remote()->transact(SET_PARAMETER, data, &reply); 118 119 return reply.readInt32(); 120 } 121 122 virtual status_t getConfig( 123 OMX_INDEXTYPE index, 124 void *params, size_t size) { 125 Parcel data, reply; 126 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 127 data.writeInt32(index); 128 data.writeInt64(size); 129 data.write(params, size); 130 remote()->transact(GET_CONFIG, data, &reply); 131 132 status_t err = reply.readInt32(); 133 if (err != OK) { 134 return err; 135 } 136 137 reply.read(params, size); 138 139 return OK; 140 } 141 142 virtual status_t setConfig( 143 OMX_INDEXTYPE index, 144 const void *params, size_t size) { 145 Parcel data, reply; 146 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 147 data.writeInt32(index); 148 data.writeInt64(size); 149 data.write(params, size); 150 remote()->transact(SET_CONFIG, data, &reply); 151 152 return reply.readInt32(); 153 } 154 155 virtual status_t setPortMode( 156 OMX_U32 port_index, IOMX::PortMode mode) { 157 Parcel data, reply; 158 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 159 data.writeInt32(port_index); 160 data.writeInt32(mode); 161 remote()->transact(SET_PORT_MODE, data, &reply); 162 163 return reply.readInt32(); 164 } 165 166 virtual status_t getGraphicBufferUsage( 167 OMX_U32 port_index, OMX_U32* usage) { 168 Parcel data, reply; 169 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 170 data.writeInt32(port_index); 171 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 172 173 status_t err = reply.readInt32(); 174 *usage = reply.readInt32(); 175 return err; 176 } 177 178 virtual status_t useBuffer( 179 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) { 180 Parcel data, reply; 181 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 182 data.writeInt32(port_index); 183 184 status_t err = omxBuf.writeToParcel(&data); 185 if (err != OK) { 186 return err; 187 } 188 189 remote()->transact(USE_BUFFER, data, &reply); 190 191 err = reply.readInt32(); 192 if (err != OK) { 193 *buffer = 0; 194 195 return err; 196 } 197 198 *buffer = (buffer_id)reply.readInt32(); 199 200 return err; 201 } 202 203 virtual status_t setInputSurface( 204 const sp<IOMXBufferSource> &bufferSource) { 205 Parcel data, reply; 206 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 207 208 data.writeStrongBinder(IInterface::asBinder(bufferSource)); 209 210 status_t err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 211 212 if (err != OK) { 213 ALOGW("binder transaction failed: %d", err); 214 return err; 215 } 216 217 err = reply.readInt32(); 218 219 return err; 220 } 221 222 virtual status_t prepareForAdaptivePlayback( 223 OMX_U32 port_index, OMX_BOOL enable, 224 OMX_U32 max_width, OMX_U32 max_height) { 225 Parcel data, reply; 226 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 227 data.writeInt32(port_index); 228 data.writeInt32((int32_t)enable); 229 data.writeInt32(max_width); 230 data.writeInt32(max_height); 231 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 232 233 status_t err = reply.readInt32(); 234 return err; 235 } 236 237 virtual status_t configureVideoTunnelMode( 238 OMX_U32 portIndex, OMX_BOOL tunneled, 239 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 240 Parcel data, reply; 241 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 242 data.writeInt32(portIndex); 243 data.writeInt32((int32_t)tunneled); 244 data.writeInt32(audioHwSync); 245 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 246 247 status_t err = reply.readInt32(); 248 if (err == OK && sidebandHandle) { 249 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 250 } 251 return err; 252 } 253 254 255 virtual status_t allocateSecureBuffer( 256 OMX_U32 port_index, size_t size, 257 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) { 258 Parcel data, reply; 259 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 260 data.writeInt32(port_index); 261 data.writeInt64(size); 262 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply); 263 264 status_t err = reply.readInt32(); 265 if (err != OK) { 266 *buffer = 0; 267 *buffer_data = NULL; 268 *native_handle = NULL; 269 return err; 270 } 271 272 *buffer = (buffer_id)reply.readInt32(); 273 *buffer_data = (void *)reply.readInt64(); 274 if (*buffer_data == NULL) { 275 *native_handle = NativeHandle::create( 276 reply.readNativeHandle(), true /* ownsHandle */); 277 } else { 278 *native_handle = NULL; 279 } 280 return err; 281 } 282 283 virtual status_t freeBuffer( 284 OMX_U32 port_index, buffer_id buffer) { 285 Parcel data, reply; 286 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 287 data.writeInt32(port_index); 288 data.writeInt32((int32_t)buffer); 289 remote()->transact(FREE_BUFFER, data, &reply); 290 291 return reply.readInt32(); 292 } 293 294 virtual status_t fillBuffer( 295 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) { 296 Parcel data, reply; 297 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 298 data.writeInt32((int32_t)buffer); 299 status_t err = omxBuf.writeToParcel(&data); 300 if (err != OK) { 301 return err; 302 } 303 data.writeInt32(fenceFd >= 0); 304 if (fenceFd >= 0) { 305 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 306 } 307 remote()->transact(FILL_BUFFER, data, &reply); 308 309 return reply.readInt32(); 310 } 311 312 virtual status_t emptyBuffer( 313 buffer_id buffer, const OMXBuffer &omxBuf, 314 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 315 Parcel data, reply; 316 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 317 data.writeInt32((int32_t)buffer); 318 status_t err = omxBuf.writeToParcel(&data); 319 if (err != OK) { 320 return err; 321 } 322 data.writeInt32(flags); 323 data.writeInt64(timestamp); 324 data.writeInt32(fenceFd >= 0); 325 if (fenceFd >= 0) { 326 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 327 } 328 remote()->transact(EMPTY_BUFFER, data, &reply); 329 330 return reply.readInt32(); 331 } 332 333 virtual status_t getExtensionIndex( 334 const char *parameter_name, 335 OMX_INDEXTYPE *index) { 336 Parcel data, reply; 337 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 338 data.writeCString(parameter_name); 339 340 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 341 342 status_t err = reply.readInt32(); 343 if (err == OK) { 344 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 345 } else { 346 *index = OMX_IndexComponentStartUnused; 347 } 348 349 return err; 350 } 351 352 virtual status_t dispatchMessage(const omx_message &msg) { 353 Parcel data, reply; 354 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 355 data.writeInt32(msg.fenceFd >= 0); 356 if (msg.fenceFd >= 0) { 357 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 358 } 359 data.writeInt32(msg.type); 360 data.write(&msg.u, sizeof(msg.u)); 361 362 remote()->transact(DISPATCH_MESSAGE, data, &reply); 363 364 return reply.readInt32(); 365 } 366 367 virtual status_t setQuirks(OMX_U32 quirks) { 368 Parcel data, reply; 369 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 370 data.writeInt32(quirks); 371 372 remote()->transact(SET_QUIRKS, data, &reply); 373 374 return reply.readInt32(); 375 } 376 }; 377 378 using ::android::hardware::media::omx::V1_0::utils::LWOmxNode; 379 class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> { 380 public: 381 HpOMXNode(const sp<IBinder>& base) : PBase(base) {} 382 383 virtual status_t freeNode() { 384 return mBase->freeNode(); 385 } 386 387 virtual status_t sendCommand( 388 OMX_COMMANDTYPE cmd, OMX_S32 param) { 389 return mBase->sendCommand(cmd, param); 390 } 391 392 virtual status_t getParameter( 393 OMX_INDEXTYPE index, void *params, size_t size) { 394 return mBase->getParameter(index, params, size); 395 } 396 397 virtual status_t setParameter( 398 OMX_INDEXTYPE index, const void *params, size_t size) { 399 return mBase->setParameter(index, params, size); 400 } 401 402 virtual status_t getConfig( 403 OMX_INDEXTYPE index, void *params, size_t size) { 404 return mBase->getConfig(index, params, size); 405 } 406 407 virtual status_t setConfig( 408 OMX_INDEXTYPE index, const void *params, size_t size) { 409 return mBase->setConfig(index, params, size); 410 } 411 412 virtual status_t setPortMode( 413 OMX_U32 port_index, IOMX::PortMode mode) { 414 return mBase->setPortMode(port_index, mode); 415 } 416 417 virtual status_t prepareForAdaptivePlayback( 418 OMX_U32 portIndex, OMX_BOOL enable, 419 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { 420 return mBase->prepareForAdaptivePlayback( 421 portIndex, enable, maxFrameWidth, maxFrameHeight); 422 } 423 424 virtual status_t configureVideoTunnelMode( 425 OMX_U32 portIndex, OMX_BOOL tunneled, 426 OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { 427 return mBase->configureVideoTunnelMode( 428 portIndex, tunneled, audioHwSync, sidebandHandle); 429 } 430 431 virtual status_t getGraphicBufferUsage( 432 OMX_U32 port_index, OMX_U32* usage) { 433 return mBase->getGraphicBufferUsage(port_index, usage); 434 } 435 436 virtual status_t setInputSurface( 437 const sp<IOMXBufferSource> &bufferSource) { 438 return mBase->setInputSurface(bufferSource); 439 } 440 441 virtual status_t allocateSecureBuffer( 442 OMX_U32 port_index, size_t size, buffer_id *buffer, 443 void **buffer_data, sp<NativeHandle> *native_handle) { 444 return mBase->allocateSecureBuffer( 445 port_index, size, buffer, buffer_data, native_handle); 446 } 447 448 virtual status_t useBuffer( 449 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) { 450 return mBase->useBuffer(port_index, omxBuf, buffer); 451 } 452 453 virtual status_t freeBuffer( 454 OMX_U32 port_index, buffer_id buffer) { 455 return mBase->freeBuffer(port_index, buffer); 456 } 457 458 virtual status_t fillBuffer( 459 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) { 460 return mBase->fillBuffer(buffer, omxBuf, fenceFd); 461 } 462 463 virtual status_t emptyBuffer( 464 buffer_id buffer, const OMXBuffer &omxBuf, 465 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) { 466 return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd); 467 } 468 469 virtual status_t getExtensionIndex( 470 const char *parameter_name, 471 OMX_INDEXTYPE *index) { 472 return mBase->getExtensionIndex(parameter_name, index); 473 } 474 475 virtual status_t dispatchMessage(const omx_message &msg) { 476 return mBase->dispatchMessage(msg); 477 } 478 }; 479 480 IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode"); 481 482 //////////////////////////////////////////////////////////////////////////////// 483 484 #define CHECK_OMX_INTERFACE(interface, data, reply) \ 485 do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \ 486 ALOGW("Call incorrectly routed to " #interface); \ 487 return PERMISSION_DENIED; \ 488 } } while (0) 489 490 status_t BnOMXNode::onTransact( 491 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 492 switch (code) { 493 case FREE_NODE: 494 { 495 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 496 497 reply->writeInt32(freeNode()); 498 499 return NO_ERROR; 500 } 501 502 case SEND_COMMAND: 503 { 504 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 505 506 OMX_COMMANDTYPE cmd = 507 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 508 509 OMX_S32 param = data.readInt32(); 510 reply->writeInt32(sendCommand(cmd, param)); 511 512 return NO_ERROR; 513 } 514 515 case GET_PARAMETER: 516 case SET_PARAMETER: 517 case GET_CONFIG: 518 case SET_CONFIG: 519 { 520 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 521 522 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 523 524 size_t size = data.readInt64(); 525 526 status_t err = NOT_ENOUGH_DATA; 527 void *params = NULL; 528 size_t pageSize = 0; 529 size_t allocSize = 0; 530 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); 531 if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) { 532 // we expect the structure to contain at least the size and 533 // version, 8 bytes total 534 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); 535 android_errorWriteLog(0x534e4554, "27207275"); 536 } else { 537 err = NO_MEMORY; 538 pageSize = (size_t) sysconf(_SC_PAGE_SIZE); 539 if (size > SIZE_MAX - (pageSize * 2)) { 540 ALOGE("requested param size too big"); 541 } else { 542 allocSize = (size + pageSize * 2) & ~(pageSize - 1); 543 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, 544 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); 545 } 546 if (params != MAP_FAILED && params != NULL) { 547 err = data.read(params, size); 548 if (err != OK) { 549 android_errorWriteLog(0x534e4554, "26914474"); 550 } else { 551 err = NOT_ENOUGH_DATA; 552 OMX_U32 declaredSize = *(OMX_U32*)params; 553 if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && 554 declaredSize > size) { 555 // the buffer says it's bigger than it actually is 556 ALOGE("b/27207275 (%u/%zu)", declaredSize, size); 557 android_errorWriteLog(0x534e4554, "27207275"); 558 } else { 559 // mark the last page as inaccessible, to avoid exploitation 560 // of codecs that access past the end of the allocation because 561 // they didn't check the size 562 if (mprotect((char*)params + allocSize - pageSize, pageSize, 563 PROT_NONE) != 0) { 564 ALOGE("mprotect failed: %s", strerror(errno)); 565 } else { 566 switch (code) { 567 case GET_PARAMETER: 568 err = getParameter(index, params, size); 569 break; 570 case SET_PARAMETER: 571 err = setParameter(index, params, size); 572 break; 573 case GET_CONFIG: 574 err = getConfig(index, params, size); 575 break; 576 case SET_CONFIG: 577 err = setConfig(index, params, size); 578 break; 579 default: 580 TRESPASS(); 581 } 582 } 583 } 584 } 585 } else { 586 ALOGE("couldn't map: %s", strerror(errno)); 587 } 588 } 589 590 reply->writeInt32(err); 591 592 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 593 reply->write(params, size); 594 } 595 596 if (params) { 597 munmap(params, allocSize); 598 } 599 params = NULL; 600 601 return NO_ERROR; 602 } 603 604 case SET_PORT_MODE: 605 { 606 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 607 OMX_U32 port_index = data.readInt32(); 608 IOMX::PortMode mode = (IOMX::PortMode) data.readInt32(); 609 reply->writeInt32(setPortMode(port_index, mode)); 610 611 return NO_ERROR; 612 } 613 614 case GET_GRAPHIC_BUFFER_USAGE: 615 { 616 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 617 618 OMX_U32 port_index = data.readInt32(); 619 620 OMX_U32 usage = 0; 621 status_t err = getGraphicBufferUsage(port_index, &usage); 622 reply->writeInt32(err); 623 reply->writeInt32(usage); 624 625 return NO_ERROR; 626 } 627 628 case USE_BUFFER: 629 { 630 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 631 632 OMX_U32 port_index = data.readInt32(); 633 634 OMXBuffer omxBuf; 635 status_t err = omxBuf.readFromParcel(&data); 636 if (err != OK) { 637 return err; 638 } 639 640 buffer_id buffer; 641 err = useBuffer(port_index, omxBuf, &buffer); 642 reply->writeInt32(err); 643 644 if (err == OK) { 645 reply->writeInt32((int32_t)buffer); 646 } 647 648 return NO_ERROR; 649 } 650 651 case SET_INPUT_SURFACE: 652 { 653 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 654 655 sp<IOMXBufferSource> bufferSource = 656 interface_cast<IOMXBufferSource>(data.readStrongBinder()); 657 658 status_t err = setInputSurface(bufferSource); 659 reply->writeInt32(err); 660 661 return NO_ERROR; 662 } 663 664 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 665 { 666 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 667 668 OMX_U32 port_index = data.readInt32(); 669 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 670 OMX_U32 max_width = data.readInt32(); 671 OMX_U32 max_height = data.readInt32(); 672 673 status_t err = prepareForAdaptivePlayback( 674 port_index, enable, max_width, max_height); 675 reply->writeInt32(err); 676 677 return NO_ERROR; 678 } 679 680 case CONFIGURE_VIDEO_TUNNEL_MODE: 681 { 682 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 683 684 OMX_U32 port_index = data.readInt32(); 685 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 686 OMX_U32 audio_hw_sync = data.readInt32(); 687 688 native_handle_t *sideband_handle = NULL; 689 status_t err = configureVideoTunnelMode( 690 port_index, tunneled, audio_hw_sync, &sideband_handle); 691 reply->writeInt32(err); 692 if(err == OK){ 693 reply->writeNativeHandle(sideband_handle); 694 } 695 696 return NO_ERROR; 697 } 698 699 case ALLOC_SECURE_BUFFER: 700 { 701 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 702 703 OMX_U32 port_index = data.readInt32(); 704 if (!isSecure() || port_index != 0 /* kPortIndexInput */) { 705 ALOGE("b/24310423"); 706 reply->writeInt32(INVALID_OPERATION); 707 return NO_ERROR; 708 } 709 710 size_t size = data.readInt64(); 711 712 buffer_id buffer; 713 void *buffer_data = NULL; 714 sp<NativeHandle> native_handle; 715 status_t err = allocateSecureBuffer( 716 port_index, size, &buffer, &buffer_data, &native_handle); 717 reply->writeInt32(err); 718 719 if (err == OK) { 720 reply->writeInt32((int32_t)buffer); 721 reply->writeInt64((uintptr_t)buffer_data); 722 if (buffer_data == NULL) { 723 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle()); 724 } 725 } 726 727 return NO_ERROR; 728 } 729 730 case FREE_BUFFER: 731 { 732 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 733 734 OMX_U32 port_index = data.readInt32(); 735 buffer_id buffer = (buffer_id)data.readInt32(); 736 reply->writeInt32(freeBuffer(port_index, buffer)); 737 738 return NO_ERROR; 739 } 740 741 case FILL_BUFFER: 742 { 743 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 744 745 buffer_id buffer = (buffer_id)data.readInt32(); 746 747 OMXBuffer omxBuf; 748 status_t err = omxBuf.readFromParcel(&data); 749 if (err != OK) { 750 return err; 751 } 752 753 bool haveFence = data.readInt32(); 754 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 755 756 reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd)); 757 758 return NO_ERROR; 759 } 760 761 case EMPTY_BUFFER: 762 { 763 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 764 765 buffer_id buffer = (buffer_id)data.readInt32(); 766 OMXBuffer omxBuf; 767 status_t err = omxBuf.readFromParcel(&data); 768 if (err != OK) { 769 return err; 770 } 771 OMX_U32 flags = data.readInt32(); 772 OMX_TICKS timestamp = data.readInt64(); 773 bool haveFence = data.readInt32(); 774 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 775 reply->writeInt32(emptyBuffer( 776 buffer, omxBuf, flags, timestamp, fenceFd)); 777 778 return NO_ERROR; 779 } 780 781 case GET_EXTENSION_INDEX: 782 { 783 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 784 785 const char *parameter_name = data.readCString(); 786 787 if (parameter_name == NULL) { 788 ALOGE("b/26392700"); 789 reply->writeInt32(INVALID_OPERATION); 790 return NO_ERROR; 791 } 792 793 OMX_INDEXTYPE index; 794 status_t err = getExtensionIndex(parameter_name, &index); 795 796 reply->writeInt32(err); 797 798 if (err == OK) { 799 reply->writeInt32(index); 800 } 801 802 return OK; 803 } 804 805 case DISPATCH_MESSAGE: 806 { 807 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 808 omx_message msg; 809 int haveFence = data.readInt32(); 810 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 811 msg.type = (typeof(msg.type))data.readInt32(); 812 status_t err = data.read(&msg.u, sizeof(msg.u)); 813 814 if (err == OK) { 815 err = dispatchMessage(msg); 816 } 817 reply->writeInt32(err); 818 819 return NO_ERROR; 820 } 821 822 default: 823 return BBinder::onTransact(code, data, reply, flags); 824 } 825 } 826 827 //////////////////////////////////////////////////////////////////////////////// 828 829 class BpOMXObserver : public BpInterface<IOMXObserver> { 830 public: 831 explicit BpOMXObserver(const sp<IBinder> &impl) 832 : BpInterface<IOMXObserver>(impl) { 833 } 834 835 virtual void onMessages(const std::list<omx_message> &messages) { 836 Parcel data, reply; 837 std::list<omx_message>::const_iterator it = messages.cbegin(); 838 if (messages.empty()) { 839 return; 840 } 841 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 842 while (it != messages.cend()) { 843 const omx_message &msg = *it++; 844 data.writeInt32(msg.fenceFd >= 0); 845 if (msg.fenceFd >= 0) { 846 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 847 } 848 data.writeInt32(msg.type); 849 data.write(&msg.u, sizeof(msg.u)); 850 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 851 } 852 data.writeInt32(-1); // mark end 853 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 854 } 855 }; 856 857 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 858 859 status_t BnOMXObserver::onTransact( 860 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 861 switch (code) { 862 case OBSERVER_ON_MSG: 863 { 864 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 865 std::list<omx_message> messages; 866 status_t err = FAILED_TRANSACTION; // must receive at least one message 867 do { 868 int haveFence = data.readInt32(); 869 if (haveFence < 0) { // we use -1 to mark end of messages 870 break; 871 } 872 omx_message msg; 873 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 874 msg.type = (typeof(msg.type))data.readInt32(); 875 err = data.read(&msg.u, sizeof(msg.u)); 876 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 877 messages.push_back(msg); 878 } while (err == OK); 879 880 if (err == OK) { 881 onMessages(messages); 882 } 883 884 return err; 885 } 886 887 default: 888 return BBinder::onTransact(code, data, reply, flags); 889 } 890 } 891 892 } // namespace android 893