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