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