IOMX.cpp revision addf2cbb120346ae42e78fa739245a353db5edad
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, OMX_TICKS origTimestamp, 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.writeInt64(origTimestamp); 486 data.writeInt32(fenceFd >= 0); 487 if (fenceFd >= 0) { 488 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 489 } 490 remote()->transact(EMPTY_GRAPHIC_BUFFER, data, &reply); 491 492 return reply.readInt32(); 493 } 494 495 virtual status_t getExtensionIndex( 496 const char *parameter_name, 497 OMX_INDEXTYPE *index) { 498 Parcel data, reply; 499 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 500 data.writeCString(parameter_name); 501 502 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 503 504 status_t err = reply.readInt32(); 505 if (err == OK) { 506 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 507 } else { 508 *index = OMX_IndexComponentStartUnused; 509 } 510 511 return err; 512 } 513 514 virtual status_t dispatchMessage(const omx_message &msg) { 515 Parcel data, reply; 516 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 517 data.writeInt32(msg.fenceFd >= 0); 518 if (msg.fenceFd >= 0) { 519 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 520 } 521 data.writeInt32(msg.type); 522 data.write(&msg.u, sizeof(msg.u)); 523 524 remote()->transact(DISPATCH_MESSAGE, data, &reply); 525 526 return reply.readInt32(); 527 } 528 529 virtual status_t setQuirks(OMX_U32 quirks) { 530 Parcel data, reply; 531 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor()); 532 data.writeInt32(quirks); 533 534 remote()->transact(SET_QUIRKS, data, &reply); 535 536 return reply.readInt32(); 537 } 538}; 539 540IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 541IMPLEMENT_META_INTERFACE(OMXNode, "android.hardware.IOMXNode"); 542 543//////////////////////////////////////////////////////////////////////////////// 544 545#define CHECK_OMX_INTERFACE(interface, data, reply) \ 546 do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \ 547 ALOGW("Call incorrectly routed to " #interface); \ 548 return PERMISSION_DENIED; \ 549 } } while (0) 550 551status_t BnOMX::onTransact( 552 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 553 switch (code) { 554 case LIST_NODES: 555 { 556 CHECK_OMX_INTERFACE(IOMX, data, reply); 557 558 List<ComponentInfo> list; 559 listNodes(&list); 560 561 reply->writeInt32(list.size()); 562 for (List<ComponentInfo>::iterator it = list.begin(); 563 it != list.end(); ++it) { 564 ComponentInfo &cur = *it; 565 566 reply->writeString8(cur.mName); 567 reply->writeInt32(cur.mRoles.size()); 568 for (List<String8>::iterator role_it = cur.mRoles.begin(); 569 role_it != cur.mRoles.end(); ++role_it) { 570 reply->writeString8(*role_it); 571 } 572 } 573 574 return NO_ERROR; 575 } 576 577 case ALLOCATE_NODE: 578 { 579 CHECK_OMX_INTERFACE(IOMX, data, reply); 580 581 const char *name = data.readCString(); 582 583 sp<IOMXObserver> observer = 584 interface_cast<IOMXObserver>(data.readStrongBinder()); 585 586 if (name == NULL || observer == NULL) { 587 ALOGE("b/26392700"); 588 reply->writeInt32(INVALID_OPERATION); 589 return NO_ERROR; 590 } 591 592 sp<IOMXNode> omxNode; 593 594 status_t err = allocateNode(name, observer, &omxNode); 595 596 reply->writeInt32(err); 597 if (err == OK) { 598 reply->writeStrongBinder(IInterface::asBinder(omxNode)); 599 } 600 601 return NO_ERROR; 602 } 603 604 case CREATE_INPUT_SURFACE: 605 { 606 CHECK_OMX_INTERFACE(IOMX, data, reply); 607 608 sp<IGraphicBufferProducer> bufferProducer; 609 sp<IGraphicBufferSource> bufferSource; 610 status_t err = createInputSurface(&bufferProducer, &bufferSource); 611 612 reply->writeInt32(err); 613 614 if (err == OK) { 615 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 616 reply->writeStrongBinder(IInterface::asBinder(bufferSource)); 617 } 618 619 return NO_ERROR; 620 } 621 622 default: 623 return BBinder::onTransact(code, data, reply, flags); 624 } 625} 626 627status_t BnOMXNode::onTransact( 628 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 629 switch (code) { 630 case FREE_NODE: 631 { 632 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 633 634 reply->writeInt32(freeNode()); 635 636 return NO_ERROR; 637 } 638 639 case SEND_COMMAND: 640 { 641 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 642 643 OMX_COMMANDTYPE cmd = 644 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 645 646 OMX_S32 param = data.readInt32(); 647 reply->writeInt32(sendCommand(cmd, param)); 648 649 return NO_ERROR; 650 } 651 652 case GET_PARAMETER: 653 case SET_PARAMETER: 654 case GET_CONFIG: 655 case SET_CONFIG: 656 { 657 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 658 659 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 660 661 size_t size = data.readInt64(); 662 663 status_t err = NOT_ENOUGH_DATA; 664 void *params = NULL; 665 size_t pageSize = 0; 666 size_t allocSize = 0; 667 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); 668 if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) { 669 // we expect the structure to contain at least the size and 670 // version, 8 bytes total 671 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); 672 android_errorWriteLog(0x534e4554, "27207275"); 673 } else { 674 err = NO_MEMORY; 675 pageSize = (size_t) sysconf(_SC_PAGE_SIZE); 676 if (size > SIZE_MAX - (pageSize * 2)) { 677 ALOGE("requested param size too big"); 678 } else { 679 allocSize = (size + pageSize * 2) & ~(pageSize - 1); 680 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, 681 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); 682 } 683 if (params != MAP_FAILED) { 684 err = data.read(params, size); 685 if (err != OK) { 686 android_errorWriteLog(0x534e4554, "26914474"); 687 } else { 688 err = NOT_ENOUGH_DATA; 689 OMX_U32 declaredSize = *(OMX_U32*)params; 690 if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && 691 declaredSize > size) { 692 // the buffer says it's bigger than it actually is 693 ALOGE("b/27207275 (%u/%zu)", declaredSize, size); 694 android_errorWriteLog(0x534e4554, "27207275"); 695 } else { 696 // mark the last page as inaccessible, to avoid exploitation 697 // of codecs that access past the end of the allocation because 698 // they didn't check the size 699 if (mprotect((char*)params + allocSize - pageSize, pageSize, 700 PROT_NONE) != 0) { 701 ALOGE("mprotect failed: %s", strerror(errno)); 702 } else { 703 switch (code) { 704 case GET_PARAMETER: 705 err = getParameter(index, params, size); 706 break; 707 case SET_PARAMETER: 708 err = setParameter(index, params, size); 709 break; 710 case GET_CONFIG: 711 err = getConfig(index, params, size); 712 break; 713 case SET_CONFIG: 714 err = setConfig(index, params, size); 715 break; 716 default: 717 TRESPASS(); 718 } 719 } 720 } 721 } 722 } else { 723 ALOGE("couldn't map: %s", strerror(errno)); 724 } 725 } 726 727 reply->writeInt32(err); 728 729 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 730 reply->write(params, size); 731 } 732 733 if (params) { 734 munmap(params, allocSize); 735 } 736 params = NULL; 737 738 return NO_ERROR; 739 } 740 741 case ENABLE_NATIVE_BUFFERS: 742 { 743 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 744 745 OMX_U32 port_index = data.readInt32(); 746 OMX_BOOL graphic = (OMX_BOOL)data.readInt32(); 747 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 748 749 status_t err = enableNativeBuffers(port_index, graphic, enable); 750 reply->writeInt32(err); 751 752 return NO_ERROR; 753 } 754 755 case GET_GRAPHIC_BUFFER_USAGE: 756 { 757 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 758 759 OMX_U32 port_index = data.readInt32(); 760 761 OMX_U32 usage = 0; 762 status_t err = getGraphicBufferUsage(port_index, &usage); 763 reply->writeInt32(err); 764 reply->writeInt32(usage); 765 766 return NO_ERROR; 767 } 768 769 case USE_BUFFER: 770 { 771 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 772 773 OMX_U32 port_index = data.readInt32(); 774 sp<IMemory> params = 775 interface_cast<IMemory>(data.readStrongBinder()); 776 OMX_U32 allottedSize = data.readInt32(); 777 778 if (params == NULL) { 779 ALOGE("b/26392700"); 780 reply->writeInt32(INVALID_OPERATION); 781 return NO_ERROR; 782 } 783 784 buffer_id buffer; 785 status_t err = useBuffer(port_index, params, &buffer, allottedSize); 786 reply->writeInt32(err); 787 788 if (err == OK) { 789 reply->writeInt32((int32_t)buffer); 790 } 791 792 return NO_ERROR; 793 } 794 795 case USE_GRAPHIC_BUFFER: 796 { 797 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 798 799 OMX_U32 port_index = data.readInt32(); 800 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 801 data.read(*graphicBuffer); 802 803 buffer_id buffer; 804 status_t err = useGraphicBuffer( 805 port_index, graphicBuffer, &buffer); 806 reply->writeInt32(err); 807 808 if (err == OK) { 809 reply->writeInt32((int32_t)buffer); 810 } 811 812 return NO_ERROR; 813 } 814 815 case UPDATE_GRAPHIC_BUFFER_IN_META: 816 { 817 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 818 819 OMX_U32 port_index = data.readInt32(); 820 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 821 data.read(*graphicBuffer); 822 buffer_id buffer = (buffer_id)data.readInt32(); 823 824 status_t err = updateGraphicBufferInMeta( 825 port_index, graphicBuffer, buffer); 826 reply->writeInt32(err); 827 828 return NO_ERROR; 829 } 830 831 case UPDATE_NATIVE_HANDLE_IN_META: 832 { 833 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 834 835 OMX_U32 port_index = data.readInt32(); 836 native_handle *handle = NULL; 837 if (data.readInt32()) { 838 handle = data.readNativeHandle(); 839 } 840 buffer_id buffer = (buffer_id)data.readInt32(); 841 842 status_t err = updateNativeHandleInMeta( 843 port_index, NativeHandle::create(handle, true /* ownshandle */), buffer); 844 reply->writeInt32(err); 845 846 return NO_ERROR; 847 } 848 849 case SET_INPUT_SURFACE: 850 { 851 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 852 853 sp<IOMXBufferSource> bufferSource = 854 interface_cast<IOMXBufferSource>(data.readStrongBinder()); 855 856 status_t err = setInputSurface(bufferSource); 857 reply->writeInt32(err); 858 859 return NO_ERROR; 860 } 861 862 case STORE_META_DATA_IN_BUFFERS: 863 { 864 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 865 866 OMX_U32 port_index = data.readInt32(); 867 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 868 869 MetadataBufferType type = (MetadataBufferType)data.readInt32(); 870 status_t err = storeMetaDataInBuffers(port_index, enable, &type); 871 872 reply->writeInt32(type); 873 reply->writeInt32(err); 874 875 return NO_ERROR; 876 } 877 878 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 879 { 880 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 881 882 OMX_U32 port_index = data.readInt32(); 883 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 884 OMX_U32 max_width = data.readInt32(); 885 OMX_U32 max_height = data.readInt32(); 886 887 status_t err = prepareForAdaptivePlayback( 888 port_index, enable, max_width, max_height); 889 reply->writeInt32(err); 890 891 return NO_ERROR; 892 } 893 894 case CONFIGURE_VIDEO_TUNNEL_MODE: 895 { 896 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 897 898 OMX_U32 port_index = data.readInt32(); 899 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 900 OMX_U32 audio_hw_sync = data.readInt32(); 901 902 native_handle_t *sideband_handle = NULL; 903 status_t err = configureVideoTunnelMode( 904 port_index, tunneled, audio_hw_sync, &sideband_handle); 905 reply->writeInt32(err); 906 if(err == OK){ 907 reply->writeNativeHandle(sideband_handle); 908 } 909 910 return NO_ERROR; 911 } 912 913 case ALLOC_SECURE_BUFFER: 914 { 915 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 916 917 OMX_U32 port_index = data.readInt32(); 918 if (!isSecure() || port_index != 0 /* kPortIndexInput */) { 919 ALOGE("b/24310423"); 920 reply->writeInt32(INVALID_OPERATION); 921 return NO_ERROR; 922 } 923 924 size_t size = data.readInt64(); 925 926 buffer_id buffer; 927 void *buffer_data = NULL; 928 sp<NativeHandle> native_handle; 929 status_t err = allocateSecureBuffer( 930 port_index, size, &buffer, &buffer_data, &native_handle); 931 reply->writeInt32(err); 932 933 if (err == OK) { 934 reply->writeInt32((int32_t)buffer); 935 reply->writeInt64((uintptr_t)buffer_data); 936 if (buffer_data == NULL) { 937 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle()); 938 } 939 } 940 941 return NO_ERROR; 942 } 943 944 case FREE_BUFFER: 945 { 946 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 947 948 OMX_U32 port_index = data.readInt32(); 949 buffer_id buffer = (buffer_id)data.readInt32(); 950 reply->writeInt32(freeBuffer(port_index, buffer)); 951 952 return NO_ERROR; 953 } 954 955 case FILL_BUFFER: 956 { 957 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 958 959 buffer_id buffer = (buffer_id)data.readInt32(); 960 bool haveFence = data.readInt32(); 961 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 962 reply->writeInt32(fillBuffer(buffer, fenceFd)); 963 964 return NO_ERROR; 965 } 966 967 case EMPTY_BUFFER: 968 { 969 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 970 971 buffer_id buffer = (buffer_id)data.readInt32(); 972 OMX_U32 range_offset = data.readInt32(); 973 OMX_U32 range_length = data.readInt32(); 974 OMX_U32 flags = data.readInt32(); 975 OMX_TICKS timestamp = data.readInt64(); 976 bool haveFence = data.readInt32(); 977 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 978 reply->writeInt32(emptyBuffer( 979 buffer, range_offset, range_length, flags, timestamp, fenceFd)); 980 981 return NO_ERROR; 982 } 983 984 case EMPTY_GRAPHIC_BUFFER: 985 { 986 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 987 988 buffer_id buffer = (buffer_id)data.readInt32(); 989 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 990 data.read(*graphicBuffer); 991 OMX_U32 flags = data.readInt32(); 992 OMX_TICKS timestamp = data.readInt64(); 993 OMX_TICKS origTimestamp = data.readInt64(); 994 bool haveFence = data.readInt32(); 995 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 996 reply->writeInt32(emptyGraphicBuffer( 997 buffer, graphicBuffer, flags, 998 timestamp, origTimestamp, fenceFd)); 999 1000 return NO_ERROR; 1001 } 1002 1003 case GET_EXTENSION_INDEX: 1004 { 1005 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 1006 1007 const char *parameter_name = data.readCString(); 1008 1009 if (parameter_name == NULL) { 1010 ALOGE("b/26392700"); 1011 reply->writeInt32(INVALID_OPERATION); 1012 return NO_ERROR; 1013 } 1014 1015 OMX_INDEXTYPE index; 1016 status_t err = getExtensionIndex(parameter_name, &index); 1017 1018 reply->writeInt32(err); 1019 1020 if (err == OK) { 1021 reply->writeInt32(index); 1022 } 1023 1024 return OK; 1025 } 1026 1027 case DISPATCH_MESSAGE: 1028 { 1029 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 1030 omx_message msg; 1031 int haveFence = data.readInt32(); 1032 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1033 msg.type = (typeof(msg.type))data.readInt32(); 1034 status_t err = data.read(&msg.u, sizeof(msg.u)); 1035 1036 if (err == OK) { 1037 err = dispatchMessage(msg); 1038 } 1039 reply->writeInt32(err); 1040 1041 return NO_ERROR; 1042 } 1043 1044 case SET_QUIRKS: 1045 { 1046 CHECK_OMX_INTERFACE(IOMXNode, data, reply); 1047 1048 OMX_U32 quirks = data.readInt32(); 1049 1050 reply->writeInt32(setQuirks(quirks)); 1051 1052 return NO_ERROR; 1053 } 1054 1055 default: 1056 return BBinder::onTransact(code, data, reply, flags); 1057 } 1058} 1059 1060//////////////////////////////////////////////////////////////////////////////// 1061 1062class BpOMXObserver : public BpInterface<IOMXObserver> { 1063public: 1064 explicit BpOMXObserver(const sp<IBinder> &impl) 1065 : BpInterface<IOMXObserver>(impl) { 1066 } 1067 1068 virtual void onMessages(const std::list<omx_message> &messages) { 1069 Parcel data, reply; 1070 std::list<omx_message>::const_iterator it = messages.cbegin(); 1071 if (messages.empty()) { 1072 return; 1073 } 1074 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1075 while (it != messages.cend()) { 1076 const omx_message &msg = *it++; 1077 data.writeInt32(msg.fenceFd >= 0); 1078 if (msg.fenceFd >= 0) { 1079 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1080 } 1081 data.writeInt32(msg.type); 1082 data.write(&msg.u, sizeof(msg.u)); 1083 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1084 } 1085 data.writeInt32(-1); // mark end 1086 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1087 } 1088}; 1089 1090IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1091 1092status_t BnOMXObserver::onTransact( 1093 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1094 switch (code) { 1095 case OBSERVER_ON_MSG: 1096 { 1097 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1098 std::list<omx_message> messages; 1099 status_t err = FAILED_TRANSACTION; // must receive at least one message 1100 do { 1101 int haveFence = data.readInt32(); 1102 if (haveFence < 0) { // we use -1 to mark end of messages 1103 break; 1104 } 1105 omx_message msg; 1106 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1107 msg.type = (typeof(msg.type))data.readInt32(); 1108 err = data.read(&msg.u, sizeof(msg.u)); 1109 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1110 messages.push_back(msg); 1111 } while (err == OK); 1112 1113 if (err == OK) { 1114 onMessages(messages); 1115 } 1116 1117 return err; 1118 } 1119 1120 default: 1121 return BBinder::onTransact(code, data, reply, flags); 1122 } 1123} 1124 1125} // namespace android 1126