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