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 <utils/NativeHandle.h> 29 30 namespace android { 31 32 enum { 33 CONNECT = IBinder::FIRST_CALL_TRANSACTION, 34 LIVES_LOCALLY, 35 LIST_NODES, 36 ALLOCATE_NODE, 37 FREE_NODE, 38 SEND_COMMAND, 39 GET_PARAMETER, 40 SET_PARAMETER, 41 GET_CONFIG, 42 SET_CONFIG, 43 GET_STATE, 44 ENABLE_NATIVE_BUFFERS, 45 USE_BUFFER, 46 USE_GRAPHIC_BUFFER, 47 CREATE_INPUT_SURFACE, 48 CREATE_PERSISTENT_INPUT_SURFACE, 49 SET_INPUT_SURFACE, 50 SIGNAL_END_OF_INPUT_STREAM, 51 STORE_META_DATA_IN_BUFFERS, 52 PREPARE_FOR_ADAPTIVE_PLAYBACK, 53 ALLOC_SECURE_BUFFER, 54 ALLOC_BUFFER_WITH_BACKUP, 55 FREE_BUFFER, 56 FILL_BUFFER, 57 EMPTY_BUFFER, 58 GET_EXTENSION_INDEX, 59 OBSERVER_ON_MSG, 60 GET_GRAPHIC_BUFFER_USAGE, 61 SET_INTERNAL_OPTION, 62 UPDATE_GRAPHIC_BUFFER_IN_META, 63 CONFIGURE_VIDEO_TUNNEL_MODE, 64 UPDATE_NATIVE_HANDLE_IN_META, 65 }; 66 67 class BpOMX : public BpInterface<IOMX> { 68 public: 69 BpOMX(const sp<IBinder> &impl) 70 : BpInterface<IOMX>(impl) { 71 } 72 73 virtual bool livesLocally(node_id node, pid_t pid) { 74 Parcel data, reply; 75 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 76 data.writeInt32((int32_t)node); 77 data.writeInt32(pid); 78 remote()->transact(LIVES_LOCALLY, data, &reply); 79 80 return reply.readInt32() != 0; 81 } 82 83 virtual status_t listNodes(List<ComponentInfo> *list) { 84 list->clear(); 85 86 Parcel data, reply; 87 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 88 remote()->transact(LIST_NODES, data, &reply); 89 90 int32_t n = reply.readInt32(); 91 for (int32_t i = 0; i < n; ++i) { 92 list->push_back(ComponentInfo()); 93 ComponentInfo &info = *--list->end(); 94 95 info.mName = reply.readString8(); 96 int32_t numRoles = reply.readInt32(); 97 for (int32_t j = 0; j < numRoles; ++j) { 98 info.mRoles.push_back(reply.readString8()); 99 } 100 } 101 102 return OK; 103 } 104 105 virtual status_t allocateNode( 106 const char *name, const sp<IOMXObserver> &observer, 107 sp<IBinder> *nodeBinder, 108 node_id *node) { 109 Parcel data, reply; 110 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 111 data.writeCString(name); 112 data.writeStrongBinder(IInterface::asBinder(observer)); 113 remote()->transact(ALLOCATE_NODE, data, &reply); 114 115 status_t err = reply.readInt32(); 116 if (err == OK) { 117 *node = (node_id)reply.readInt32(); 118 if (nodeBinder != NULL) { 119 *nodeBinder = remote(); 120 } 121 } else { 122 *node = 0; 123 } 124 125 return err; 126 } 127 128 virtual status_t freeNode(node_id node) { 129 Parcel data, reply; 130 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 131 data.writeInt32((int32_t)node); 132 remote()->transact(FREE_NODE, data, &reply); 133 134 return reply.readInt32(); 135 } 136 137 virtual status_t sendCommand( 138 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 139 Parcel data, reply; 140 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 141 data.writeInt32((int32_t)node); 142 data.writeInt32(cmd); 143 data.writeInt32(param); 144 remote()->transact(SEND_COMMAND, data, &reply); 145 146 return reply.readInt32(); 147 } 148 149 virtual status_t getParameter( 150 node_id node, OMX_INDEXTYPE index, 151 void *params, size_t size) { 152 Parcel data, reply; 153 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 154 data.writeInt32((int32_t)node); 155 data.writeInt32(index); 156 data.writeInt64(size); 157 data.write(params, size); 158 remote()->transact(GET_PARAMETER, data, &reply); 159 160 status_t err = reply.readInt32(); 161 if (err != OK) { 162 return err; 163 } 164 165 reply.read(params, size); 166 167 return OK; 168 } 169 170 virtual status_t setParameter( 171 node_id node, OMX_INDEXTYPE index, 172 const void *params, size_t size) { 173 Parcel data, reply; 174 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 175 data.writeInt32((int32_t)node); 176 data.writeInt32(index); 177 data.writeInt64(size); 178 data.write(params, size); 179 remote()->transact(SET_PARAMETER, data, &reply); 180 181 return reply.readInt32(); 182 } 183 184 virtual status_t getConfig( 185 node_id node, OMX_INDEXTYPE index, 186 void *params, size_t size) { 187 Parcel data, reply; 188 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 189 data.writeInt32((int32_t)node); 190 data.writeInt32(index); 191 data.writeInt64(size); 192 data.write(params, size); 193 remote()->transact(GET_CONFIG, data, &reply); 194 195 status_t err = reply.readInt32(); 196 if (err != OK) { 197 return err; 198 } 199 200 reply.read(params, size); 201 202 return OK; 203 } 204 205 virtual status_t setConfig( 206 node_id node, OMX_INDEXTYPE index, 207 const void *params, size_t size) { 208 Parcel data, reply; 209 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 210 data.writeInt32((int32_t)node); 211 data.writeInt32(index); 212 data.writeInt64(size); 213 data.write(params, size); 214 remote()->transact(SET_CONFIG, data, &reply); 215 216 return reply.readInt32(); 217 } 218 219 virtual status_t getState( 220 node_id node, OMX_STATETYPE* state) { 221 Parcel data, reply; 222 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 223 data.writeInt32((int32_t)node); 224 remote()->transact(GET_STATE, data, &reply); 225 226 *state = static_cast<OMX_STATETYPE>(reply.readInt32()); 227 return reply.readInt32(); 228 } 229 230 virtual status_t enableNativeBuffers( 231 node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) { 232 Parcel data, reply; 233 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 234 data.writeInt32((int32_t)node); 235 data.writeInt32(port_index); 236 data.writeInt32((uint32_t)graphic); 237 data.writeInt32((uint32_t)enable); 238 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply); 239 240 status_t err = reply.readInt32(); 241 return err; 242 } 243 244 virtual status_t getGraphicBufferUsage( 245 node_id node, OMX_U32 port_index, OMX_U32* usage) { 246 Parcel data, reply; 247 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 248 data.writeInt32((int32_t)node); 249 data.writeInt32(port_index); 250 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 251 252 status_t err = reply.readInt32(); 253 *usage = reply.readInt32(); 254 return err; 255 } 256 257 virtual status_t useBuffer( 258 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 259 buffer_id *buffer, OMX_U32 allottedSize) { 260 Parcel data, reply; 261 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 262 data.writeInt32((int32_t)node); 263 data.writeInt32(port_index); 264 data.writeStrongBinder(IInterface::asBinder(params)); 265 data.writeInt32(allottedSize); 266 remote()->transact(USE_BUFFER, data, &reply); 267 268 status_t err = reply.readInt32(); 269 if (err != OK) { 270 *buffer = 0; 271 272 return err; 273 } 274 275 *buffer = (buffer_id)reply.readInt32(); 276 277 return err; 278 } 279 280 281 virtual status_t useGraphicBuffer( 282 node_id node, OMX_U32 port_index, 283 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 284 Parcel data, reply; 285 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 286 data.writeInt32((int32_t)node); 287 data.writeInt32(port_index); 288 data.write(*graphicBuffer); 289 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); 290 291 status_t err = reply.readInt32(); 292 if (err != OK) { 293 *buffer = 0; 294 295 return err; 296 } 297 298 *buffer = (buffer_id)reply.readInt32(); 299 300 return err; 301 } 302 303 virtual status_t updateGraphicBufferInMeta( 304 node_id node, OMX_U32 port_index, 305 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 306 Parcel data, reply; 307 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 308 data.writeInt32((int32_t)node); 309 data.writeInt32(port_index); 310 data.write(*graphicBuffer); 311 data.writeInt32((int32_t)buffer); 312 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply); 313 314 status_t err = reply.readInt32(); 315 return err; 316 } 317 318 virtual status_t updateNativeHandleInMeta( 319 node_id node, OMX_U32 port_index, 320 const sp<NativeHandle> &nativeHandle, buffer_id buffer) { 321 Parcel data, reply; 322 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 323 data.writeInt32((int32_t)node); 324 data.writeInt32(port_index); 325 data.writeInt32(nativeHandle != NULL); 326 if (nativeHandle != NULL) { 327 data.writeNativeHandle(nativeHandle->handle()); 328 } 329 data.writeInt32((int32_t)buffer); 330 remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply); 331 332 status_t err = reply.readInt32(); 333 return err; 334 } 335 336 virtual status_t createInputSurface( 337 node_id node, OMX_U32 port_index, android_dataspace dataSpace, 338 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { 339 Parcel data, reply; 340 status_t err; 341 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 342 data.writeInt32((int32_t)node); 343 data.writeInt32(port_index); 344 data.writeInt32(dataSpace); 345 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply); 346 if (err != OK) { 347 ALOGW("binder transaction failed: %d", err); 348 return err; 349 } 350 351 // read type even if createInputSurface failed 352 int negotiatedType = reply.readInt32(); 353 if (type != NULL) { 354 *type = (MetadataBufferType)negotiatedType; 355 } 356 357 err = reply.readInt32(); 358 if (err != OK) { 359 return err; 360 } 361 362 *bufferProducer = IGraphicBufferProducer::asInterface( 363 reply.readStrongBinder()); 364 365 return err; 366 } 367 368 virtual status_t createPersistentInputSurface( 369 sp<IGraphicBufferProducer> *bufferProducer, 370 sp<IGraphicBufferConsumer> *bufferConsumer) { 371 Parcel data, reply; 372 status_t err; 373 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 374 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply); 375 if (err != OK) { 376 ALOGW("binder transaction failed: %d", err); 377 return err; 378 } 379 380 err = reply.readInt32(); 381 if (err != OK) { 382 return err; 383 } 384 385 *bufferProducer = IGraphicBufferProducer::asInterface( 386 reply.readStrongBinder()); 387 *bufferConsumer = IGraphicBufferConsumer::asInterface( 388 reply.readStrongBinder()); 389 390 return err; 391 } 392 393 virtual status_t setInputSurface( 394 node_id node, OMX_U32 port_index, 395 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) { 396 Parcel data, reply; 397 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 398 status_t err; 399 data.writeInt32((int32_t)node); 400 data.writeInt32(port_index); 401 data.writeStrongBinder(IInterface::asBinder(bufferConsumer)); 402 403 err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 404 405 if (err != OK) { 406 ALOGW("binder transaction failed: %d", err); 407 return err; 408 } 409 410 // read type even if setInputSurface failed 411 int negotiatedType = reply.readInt32(); 412 if (type != NULL) { 413 *type = (MetadataBufferType)negotiatedType; 414 } 415 416 return reply.readInt32(); 417 } 418 419 virtual status_t signalEndOfInputStream(node_id node) { 420 Parcel data, reply; 421 status_t err; 422 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 423 data.writeInt32((int32_t)node); 424 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply); 425 if (err != OK) { 426 ALOGW("binder transaction failed: %d", err); 427 return err; 428 } 429 430 return reply.readInt32(); 431 } 432 433 virtual status_t storeMetaDataInBuffers( 434 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) { 435 Parcel data, reply; 436 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 437 data.writeInt32((int32_t)node); 438 data.writeInt32(port_index); 439 data.writeInt32((int32_t)enable); 440 data.writeInt32(type == NULL ? kMetadataBufferTypeANWBuffer : *type); 441 442 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); 443 444 // read type even storeMetaDataInBuffers failed 445 int negotiatedType = reply.readInt32(); 446 if (type != NULL) { 447 *type = (MetadataBufferType)negotiatedType; 448 } 449 450 return reply.readInt32(); 451 } 452 453 virtual status_t prepareForAdaptivePlayback( 454 node_id node, OMX_U32 port_index, OMX_BOOL enable, 455 OMX_U32 max_width, OMX_U32 max_height) { 456 Parcel data, reply; 457 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 458 data.writeInt32((int32_t)node); 459 data.writeInt32(port_index); 460 data.writeInt32((int32_t)enable); 461 data.writeInt32(max_width); 462 data.writeInt32(max_height); 463 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 464 465 status_t err = reply.readInt32(); 466 return err; 467 } 468 469 virtual status_t configureVideoTunnelMode( 470 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, 471 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 472 Parcel data, reply; 473 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 474 data.writeInt32((int32_t)node); 475 data.writeInt32(portIndex); 476 data.writeInt32((int32_t)tunneled); 477 data.writeInt32(audioHwSync); 478 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 479 480 status_t err = reply.readInt32(); 481 if (err == OK && sidebandHandle) { 482 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 483 } 484 return err; 485 } 486 487 488 virtual status_t allocateSecureBuffer( 489 node_id node, OMX_U32 port_index, size_t size, 490 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) { 491 Parcel data, reply; 492 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 493 data.writeInt32((int32_t)node); 494 data.writeInt32(port_index); 495 data.writeInt64(size); 496 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply); 497 498 status_t err = reply.readInt32(); 499 if (err != OK) { 500 *buffer = 0; 501 *buffer_data = NULL; 502 *native_handle = NULL; 503 return err; 504 } 505 506 *buffer = (buffer_id)reply.readInt32(); 507 *buffer_data = (void *)reply.readInt64(); 508 if (*buffer_data == NULL) { 509 *native_handle = NativeHandle::create( 510 reply.readNativeHandle(), true /* ownsHandle */); 511 } else { 512 *native_handle = NULL; 513 } 514 return err; 515 } 516 517 virtual status_t allocateBufferWithBackup( 518 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 519 buffer_id *buffer, OMX_U32 allottedSize) { 520 Parcel data, reply; 521 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 522 data.writeInt32((int32_t)node); 523 data.writeInt32(port_index); 524 data.writeStrongBinder(IInterface::asBinder(params)); 525 data.writeInt32(allottedSize); 526 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 527 528 status_t err = reply.readInt32(); 529 if (err != OK) { 530 *buffer = 0; 531 532 return err; 533 } 534 535 *buffer = (buffer_id)reply.readInt32(); 536 537 return err; 538 } 539 540 virtual status_t freeBuffer( 541 node_id node, OMX_U32 port_index, buffer_id buffer) { 542 Parcel data, reply; 543 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 544 data.writeInt32((int32_t)node); 545 data.writeInt32(port_index); 546 data.writeInt32((int32_t)buffer); 547 remote()->transact(FREE_BUFFER, data, &reply); 548 549 return reply.readInt32(); 550 } 551 552 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) { 553 Parcel data, reply; 554 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 555 data.writeInt32((int32_t)node); 556 data.writeInt32((int32_t)buffer); 557 data.writeInt32(fenceFd >= 0); 558 if (fenceFd >= 0) { 559 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 560 } 561 remote()->transact(FILL_BUFFER, data, &reply); 562 563 return reply.readInt32(); 564 } 565 566 virtual status_t emptyBuffer( 567 node_id node, 568 buffer_id buffer, 569 OMX_U32 range_offset, OMX_U32 range_length, 570 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 571 Parcel data, reply; 572 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 573 data.writeInt32((int32_t)node); 574 data.writeInt32((int32_t)buffer); 575 data.writeInt32(range_offset); 576 data.writeInt32(range_length); 577 data.writeInt32(flags); 578 data.writeInt64(timestamp); 579 data.writeInt32(fenceFd >= 0); 580 if (fenceFd >= 0) { 581 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 582 } 583 remote()->transact(EMPTY_BUFFER, data, &reply); 584 585 return reply.readInt32(); 586 } 587 588 virtual status_t getExtensionIndex( 589 node_id node, 590 const char *parameter_name, 591 OMX_INDEXTYPE *index) { 592 Parcel data, reply; 593 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 594 data.writeInt32((int32_t)node); 595 data.writeCString(parameter_name); 596 597 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 598 599 status_t err = reply.readInt32(); 600 if (err == OK) { 601 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 602 } else { 603 *index = OMX_IndexComponentStartUnused; 604 } 605 606 return err; 607 } 608 609 virtual status_t setInternalOption( 610 node_id node, 611 OMX_U32 port_index, 612 InternalOptionType type, 613 const void *optionData, 614 size_t size) { 615 Parcel data, reply; 616 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 617 data.writeInt32((int32_t)node); 618 data.writeInt32(port_index); 619 data.writeInt64(size); 620 data.write(optionData, size); 621 data.writeInt32(type); 622 remote()->transact(SET_INTERNAL_OPTION, data, &reply); 623 624 return reply.readInt32(); 625 } 626 }; 627 628 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 629 630 //////////////////////////////////////////////////////////////////////////////// 631 632 #define CHECK_OMX_INTERFACE(interface, data, reply) \ 633 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 634 ALOGW("Call incorrectly routed to " #interface); \ 635 return PERMISSION_DENIED; \ 636 } } while (0) 637 638 status_t BnOMX::onTransact( 639 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 640 switch (code) { 641 case LIVES_LOCALLY: 642 { 643 CHECK_OMX_INTERFACE(IOMX, data, reply); 644 node_id node = (node_id)data.readInt32(); 645 pid_t pid = (pid_t)data.readInt32(); 646 reply->writeInt32(livesLocally(node, pid)); 647 648 return OK; 649 } 650 651 case LIST_NODES: 652 { 653 CHECK_OMX_INTERFACE(IOMX, data, reply); 654 655 List<ComponentInfo> list; 656 listNodes(&list); 657 658 reply->writeInt32(list.size()); 659 for (List<ComponentInfo>::iterator it = list.begin(); 660 it != list.end(); ++it) { 661 ComponentInfo &cur = *it; 662 663 reply->writeString8(cur.mName); 664 reply->writeInt32(cur.mRoles.size()); 665 for (List<String8>::iterator role_it = cur.mRoles.begin(); 666 role_it != cur.mRoles.end(); ++role_it) { 667 reply->writeString8(*role_it); 668 } 669 } 670 671 return NO_ERROR; 672 } 673 674 case ALLOCATE_NODE: 675 { 676 CHECK_OMX_INTERFACE(IOMX, data, reply); 677 678 const char *name = data.readCString(); 679 680 sp<IOMXObserver> observer = 681 interface_cast<IOMXObserver>(data.readStrongBinder()); 682 683 if (name == NULL || observer == NULL) { 684 ALOGE("b/26392700"); 685 reply->writeInt32(INVALID_OPERATION); 686 return NO_ERROR; 687 } 688 689 node_id node; 690 691 status_t err = allocateNode(name, observer, 692 NULL /* nodeBinder */, &node); 693 reply->writeInt32(err); 694 if (err == OK) { 695 reply->writeInt32((int32_t)node); 696 } 697 698 return NO_ERROR; 699 } 700 701 case FREE_NODE: 702 { 703 CHECK_OMX_INTERFACE(IOMX, data, reply); 704 705 node_id node = (node_id)data.readInt32(); 706 707 reply->writeInt32(freeNode(node)); 708 709 return NO_ERROR; 710 } 711 712 case SEND_COMMAND: 713 { 714 CHECK_OMX_INTERFACE(IOMX, data, reply); 715 716 node_id node = (node_id)data.readInt32(); 717 718 OMX_COMMANDTYPE cmd = 719 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 720 721 OMX_S32 param = data.readInt32(); 722 reply->writeInt32(sendCommand(node, cmd, param)); 723 724 return NO_ERROR; 725 } 726 727 case GET_PARAMETER: 728 case SET_PARAMETER: 729 case GET_CONFIG: 730 case SET_CONFIG: 731 case SET_INTERNAL_OPTION: 732 { 733 CHECK_OMX_INTERFACE(IOMX, data, reply); 734 735 node_id node = (node_id)data.readInt32(); 736 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 737 738 size_t size = data.readInt64(); 739 740 status_t err = NOT_ENOUGH_DATA; 741 void *params = NULL; 742 size_t pageSize = 0; 743 size_t allocSize = 0; 744 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); 745 if ((isUsageBits && size < 4) || 746 (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) { 747 // we expect the structure to contain at least the size and 748 // version, 8 bytes total 749 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); 750 android_errorWriteLog(0x534e4554, "27207275"); 751 } else { 752 err = NO_MEMORY; 753 pageSize = (size_t) sysconf(_SC_PAGE_SIZE); 754 if (size > SIZE_MAX - (pageSize * 2)) { 755 ALOGE("requested param size too big"); 756 } else { 757 allocSize = (size + pageSize * 2) & ~(pageSize - 1); 758 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, 759 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); 760 } 761 if (params != MAP_FAILED) { 762 err = data.read(params, size); 763 if (err != OK) { 764 android_errorWriteLog(0x534e4554, "26914474"); 765 } else { 766 err = NOT_ENOUGH_DATA; 767 OMX_U32 declaredSize = *(OMX_U32*)params; 768 if (code != SET_INTERNAL_OPTION && 769 index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && 770 declaredSize > size) { 771 // the buffer says it's bigger than it actually is 772 ALOGE("b/27207275 (%u/%zu)", declaredSize, size); 773 android_errorWriteLog(0x534e4554, "27207275"); 774 } else { 775 // mark the last page as inaccessible, to avoid exploitation 776 // of codecs that access past the end of the allocation because 777 // they didn't check the size 778 if (mprotect((char*)params + allocSize - pageSize, pageSize, 779 PROT_NONE) != 0) { 780 ALOGE("mprotect failed: %s", strerror(errno)); 781 } else { 782 switch (code) { 783 case GET_PARAMETER: 784 err = getParameter(node, index, params, size); 785 break; 786 case SET_PARAMETER: 787 err = setParameter(node, index, params, size); 788 break; 789 case GET_CONFIG: 790 err = getConfig(node, index, params, size); 791 break; 792 case SET_CONFIG: 793 err = setConfig(node, index, params, size); 794 break; 795 case SET_INTERNAL_OPTION: 796 { 797 InternalOptionType type = 798 (InternalOptionType)data.readInt32(); 799 800 err = setInternalOption(node, index, type, params, size); 801 break; 802 } 803 804 default: 805 TRESPASS(); 806 } 807 } 808 } 809 } 810 } else { 811 ALOGE("couldn't map: %s", strerror(errno)); 812 } 813 } 814 815 reply->writeInt32(err); 816 817 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 818 reply->write(params, size); 819 } 820 821 if (params) { 822 munmap(params, allocSize); 823 } 824 params = NULL; 825 826 return NO_ERROR; 827 } 828 829 case GET_STATE: 830 { 831 CHECK_OMX_INTERFACE(IOMX, data, reply); 832 833 node_id node = (node_id)data.readInt32(); 834 OMX_STATETYPE state = OMX_StateInvalid; 835 836 status_t err = getState(node, &state); 837 reply->writeInt32(state); 838 reply->writeInt32(err); 839 840 return NO_ERROR; 841 } 842 843 case ENABLE_NATIVE_BUFFERS: 844 { 845 CHECK_OMX_INTERFACE(IOMX, data, reply); 846 847 node_id node = (node_id)data.readInt32(); 848 OMX_U32 port_index = data.readInt32(); 849 OMX_BOOL graphic = (OMX_BOOL)data.readInt32(); 850 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 851 852 status_t err = enableNativeBuffers(node, port_index, graphic, enable); 853 reply->writeInt32(err); 854 855 return NO_ERROR; 856 } 857 858 case GET_GRAPHIC_BUFFER_USAGE: 859 { 860 CHECK_OMX_INTERFACE(IOMX, data, reply); 861 862 node_id node = (node_id)data.readInt32(); 863 OMX_U32 port_index = data.readInt32(); 864 865 OMX_U32 usage = 0; 866 status_t err = getGraphicBufferUsage(node, port_index, &usage); 867 reply->writeInt32(err); 868 reply->writeInt32(usage); 869 870 return NO_ERROR; 871 } 872 873 case USE_BUFFER: 874 { 875 CHECK_OMX_INTERFACE(IOMX, data, reply); 876 877 node_id node = (node_id)data.readInt32(); 878 OMX_U32 port_index = data.readInt32(); 879 sp<IMemory> params = 880 interface_cast<IMemory>(data.readStrongBinder()); 881 OMX_U32 allottedSize = data.readInt32(); 882 883 if (params == NULL) { 884 ALOGE("b/26392700"); 885 reply->writeInt32(INVALID_OPERATION); 886 return NO_ERROR; 887 } 888 889 buffer_id buffer; 890 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 891 reply->writeInt32(err); 892 893 if (err == OK) { 894 reply->writeInt32((int32_t)buffer); 895 } 896 897 return NO_ERROR; 898 } 899 900 case USE_GRAPHIC_BUFFER: 901 { 902 CHECK_OMX_INTERFACE(IOMX, data, reply); 903 904 node_id node = (node_id)data.readInt32(); 905 OMX_U32 port_index = data.readInt32(); 906 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 907 data.read(*graphicBuffer); 908 909 buffer_id buffer; 910 status_t err = useGraphicBuffer( 911 node, port_index, graphicBuffer, &buffer); 912 reply->writeInt32(err); 913 914 if (err == OK) { 915 reply->writeInt32((int32_t)buffer); 916 } 917 918 return NO_ERROR; 919 } 920 921 case UPDATE_GRAPHIC_BUFFER_IN_META: 922 { 923 CHECK_OMX_INTERFACE(IOMX, data, reply); 924 925 node_id node = (node_id)data.readInt32(); 926 OMX_U32 port_index = data.readInt32(); 927 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 928 data.read(*graphicBuffer); 929 buffer_id buffer = (buffer_id)data.readInt32(); 930 931 status_t err = updateGraphicBufferInMeta( 932 node, port_index, graphicBuffer, buffer); 933 reply->writeInt32(err); 934 935 return NO_ERROR; 936 } 937 938 case UPDATE_NATIVE_HANDLE_IN_META: 939 { 940 CHECK_OMX_INTERFACE(IOMX, data, reply); 941 942 node_id node = (node_id)data.readInt32(); 943 OMX_U32 port_index = data.readInt32(); 944 native_handle *handle = NULL; 945 if (data.readInt32()) { 946 handle = data.readNativeHandle(); 947 } 948 buffer_id buffer = (buffer_id)data.readInt32(); 949 950 status_t err = updateNativeHandleInMeta( 951 node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer); 952 reply->writeInt32(err); 953 954 return NO_ERROR; 955 } 956 957 case CREATE_INPUT_SURFACE: 958 { 959 CHECK_OMX_INTERFACE(IOMX, data, reply); 960 961 node_id node = (node_id)data.readInt32(); 962 OMX_U32 port_index = data.readInt32(); 963 android_dataspace dataSpace = (android_dataspace)data.readInt32(); 964 965 sp<IGraphicBufferProducer> bufferProducer; 966 MetadataBufferType type = kMetadataBufferTypeInvalid; 967 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type); 968 969 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 970 android_errorWriteLog(0x534e4554, "26324358"); 971 } 972 973 reply->writeInt32(type); 974 reply->writeInt32(err); 975 976 if (err == OK) { 977 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 978 } 979 980 return NO_ERROR; 981 } 982 983 case CREATE_PERSISTENT_INPUT_SURFACE: 984 { 985 CHECK_OMX_INTERFACE(IOMX, data, reply); 986 987 sp<IGraphicBufferProducer> bufferProducer; 988 sp<IGraphicBufferConsumer> bufferConsumer; 989 status_t err = createPersistentInputSurface( 990 &bufferProducer, &bufferConsumer); 991 992 reply->writeInt32(err); 993 994 if (err == OK) { 995 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 996 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 997 } 998 999 return NO_ERROR; 1000 } 1001 1002 case SET_INPUT_SURFACE: 1003 { 1004 CHECK_OMX_INTERFACE(IOMX, data, reply); 1005 1006 node_id node = (node_id)data.readInt32(); 1007 OMX_U32 port_index = data.readInt32(); 1008 1009 sp<IGraphicBufferConsumer> bufferConsumer = 1010 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 1011 1012 MetadataBufferType type = kMetadataBufferTypeInvalid; 1013 1014 status_t err = INVALID_OPERATION; 1015 if (bufferConsumer == NULL) { 1016 ALOGE("b/26392700"); 1017 } else { 1018 err = setInputSurface(node, port_index, bufferConsumer, &type); 1019 1020 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 1021 android_errorWriteLog(0x534e4554, "26324358"); 1022 } 1023 } 1024 1025 reply->writeInt32(type); 1026 reply->writeInt32(err); 1027 return NO_ERROR; 1028 } 1029 1030 case SIGNAL_END_OF_INPUT_STREAM: 1031 { 1032 CHECK_OMX_INTERFACE(IOMX, data, reply); 1033 1034 node_id node = (node_id)data.readInt32(); 1035 1036 status_t err = signalEndOfInputStream(node); 1037 reply->writeInt32(err); 1038 1039 return NO_ERROR; 1040 } 1041 1042 case STORE_META_DATA_IN_BUFFERS: 1043 { 1044 CHECK_OMX_INTERFACE(IOMX, data, reply); 1045 1046 node_id node = (node_id)data.readInt32(); 1047 OMX_U32 port_index = data.readInt32(); 1048 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1049 1050 MetadataBufferType type = (MetadataBufferType)data.readInt32(); 1051 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 1052 1053 reply->writeInt32(type); 1054 reply->writeInt32(err); 1055 1056 return NO_ERROR; 1057 } 1058 1059 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 1060 { 1061 CHECK_OMX_INTERFACE(IOMX, data, reply); 1062 1063 node_id node = (node_id)data.readInt32(); 1064 OMX_U32 port_index = data.readInt32(); 1065 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1066 OMX_U32 max_width = data.readInt32(); 1067 OMX_U32 max_height = data.readInt32(); 1068 1069 status_t err = prepareForAdaptivePlayback( 1070 node, port_index, enable, max_width, max_height); 1071 reply->writeInt32(err); 1072 1073 return NO_ERROR; 1074 } 1075 1076 case CONFIGURE_VIDEO_TUNNEL_MODE: 1077 { 1078 CHECK_OMX_INTERFACE(IOMX, data, reply); 1079 1080 node_id node = (node_id)data.readInt32(); 1081 OMX_U32 port_index = data.readInt32(); 1082 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 1083 OMX_U32 audio_hw_sync = data.readInt32(); 1084 1085 native_handle_t *sideband_handle = NULL; 1086 status_t err = configureVideoTunnelMode( 1087 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 1088 reply->writeInt32(err); 1089 if(err == OK){ 1090 reply->writeNativeHandle(sideband_handle); 1091 } 1092 1093 return NO_ERROR; 1094 } 1095 1096 case ALLOC_SECURE_BUFFER: 1097 { 1098 CHECK_OMX_INTERFACE(IOMX, data, reply); 1099 1100 node_id node = (node_id)data.readInt32(); 1101 OMX_U32 port_index = data.readInt32(); 1102 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 1103 ALOGE("b/24310423"); 1104 reply->writeInt32(INVALID_OPERATION); 1105 return NO_ERROR; 1106 } 1107 1108 size_t size = data.readInt64(); 1109 1110 buffer_id buffer; 1111 void *buffer_data = NULL; 1112 sp<NativeHandle> native_handle; 1113 status_t err = allocateSecureBuffer( 1114 node, port_index, size, &buffer, &buffer_data, &native_handle); 1115 reply->writeInt32(err); 1116 1117 if (err == OK) { 1118 reply->writeInt32((int32_t)buffer); 1119 reply->writeInt64((uintptr_t)buffer_data); 1120 if (buffer_data == NULL) { 1121 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle()); 1122 } 1123 } 1124 1125 return NO_ERROR; 1126 } 1127 1128 case ALLOC_BUFFER_WITH_BACKUP: 1129 { 1130 CHECK_OMX_INTERFACE(IOMX, data, reply); 1131 1132 node_id node = (node_id)data.readInt32(); 1133 OMX_U32 port_index = data.readInt32(); 1134 sp<IMemory> params = 1135 interface_cast<IMemory>(data.readStrongBinder()); 1136 OMX_U32 allottedSize = data.readInt32(); 1137 1138 if (params == NULL) { 1139 ALOGE("b/26392700"); 1140 reply->writeInt32(INVALID_OPERATION); 1141 return NO_ERROR; 1142 } 1143 1144 buffer_id buffer; 1145 status_t err = allocateBufferWithBackup( 1146 node, port_index, params, &buffer, allottedSize); 1147 1148 reply->writeInt32(err); 1149 1150 if (err == OK) { 1151 reply->writeInt32((int32_t)buffer); 1152 } 1153 1154 return NO_ERROR; 1155 } 1156 1157 case FREE_BUFFER: 1158 { 1159 CHECK_OMX_INTERFACE(IOMX, data, reply); 1160 1161 node_id node = (node_id)data.readInt32(); 1162 OMX_U32 port_index = data.readInt32(); 1163 buffer_id buffer = (buffer_id)data.readInt32(); 1164 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1165 1166 return NO_ERROR; 1167 } 1168 1169 case FILL_BUFFER: 1170 { 1171 CHECK_OMX_INTERFACE(IOMX, data, reply); 1172 1173 node_id node = (node_id)data.readInt32(); 1174 buffer_id buffer = (buffer_id)data.readInt32(); 1175 bool haveFence = data.readInt32(); 1176 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1177 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1178 1179 return NO_ERROR; 1180 } 1181 1182 case EMPTY_BUFFER: 1183 { 1184 CHECK_OMX_INTERFACE(IOMX, data, reply); 1185 1186 node_id node = (node_id)data.readInt32(); 1187 buffer_id buffer = (buffer_id)data.readInt32(); 1188 OMX_U32 range_offset = data.readInt32(); 1189 OMX_U32 range_length = data.readInt32(); 1190 OMX_U32 flags = data.readInt32(); 1191 OMX_TICKS timestamp = data.readInt64(); 1192 bool haveFence = data.readInt32(); 1193 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1194 reply->writeInt32(emptyBuffer( 1195 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1196 1197 return NO_ERROR; 1198 } 1199 1200 case GET_EXTENSION_INDEX: 1201 { 1202 CHECK_OMX_INTERFACE(IOMX, data, reply); 1203 1204 node_id node = (node_id)data.readInt32(); 1205 const char *parameter_name = data.readCString(); 1206 1207 if (parameter_name == NULL) { 1208 ALOGE("b/26392700"); 1209 reply->writeInt32(INVALID_OPERATION); 1210 return NO_ERROR; 1211 } 1212 1213 OMX_INDEXTYPE index; 1214 status_t err = getExtensionIndex(node, parameter_name, &index); 1215 1216 reply->writeInt32(err); 1217 1218 if (err == OK) { 1219 reply->writeInt32(index); 1220 } 1221 1222 return OK; 1223 } 1224 1225 default: 1226 return BBinder::onTransact(code, data, reply, flags); 1227 } 1228 } 1229 1230 //////////////////////////////////////////////////////////////////////////////// 1231 1232 class BpOMXObserver : public BpInterface<IOMXObserver> { 1233 public: 1234 BpOMXObserver(const sp<IBinder> &impl) 1235 : BpInterface<IOMXObserver>(impl) { 1236 } 1237 1238 virtual void onMessages(const std::list<omx_message> &messages) { 1239 Parcel data, reply; 1240 std::list<omx_message>::const_iterator it = messages.cbegin(); 1241 bool first = true; 1242 while (it != messages.cend()) { 1243 const omx_message &msg = *it++; 1244 if (first) { 1245 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1246 data.writeInt32(msg.node); 1247 first = false; 1248 } 1249 data.writeInt32(msg.fenceFd >= 0); 1250 if (msg.fenceFd >= 0) { 1251 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1252 } 1253 data.writeInt32(msg.type); 1254 data.write(&msg.u, sizeof(msg.u)); 1255 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1256 } 1257 if (!first) { 1258 data.writeInt32(-1); // mark end 1259 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1260 } 1261 } 1262 }; 1263 1264 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1265 1266 status_t BnOMXObserver::onTransact( 1267 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1268 switch (code) { 1269 case OBSERVER_ON_MSG: 1270 { 1271 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1272 IOMX::node_id node = data.readInt32(); 1273 std::list<omx_message> messages; 1274 status_t err = FAILED_TRANSACTION; // must receive at least one message 1275 do { 1276 int haveFence = data.readInt32(); 1277 if (haveFence < 0) { // we use -1 to mark end of messages 1278 break; 1279 } 1280 omx_message msg; 1281 msg.node = node; 1282 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1283 msg.type = (typeof(msg.type))data.readInt32(); 1284 err = data.read(&msg.u, sizeof(msg.u)); 1285 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1286 messages.push_back(msg); 1287 } while (err == OK); 1288 1289 if (err == OK) { 1290 onMessages(messages); 1291 } 1292 1293 return err; 1294 } 1295 1296 default: 1297 return BBinder::onTransact(code, data, reply, flags); 1298 } 1299 } 1300 1301 } // namespace android 1302