IOMX.cpp revision 6cf9a1238986880536de705255f7c2c91c1ba719
1debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor/* 219a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor * Copyright (c) 2009 The Android Open Source Project 3debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * 4debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * Licensed under the Apache License, Version 2.0 (the "License"); 5debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * you may not use this file except in compliance with the License. 6debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * You may obtain a copy of the License at 7debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * 80c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor * http://www.apache.org/licenses/LICENSE-2.0 978d2fda9403bf61e9d2b8a0686b88d03064a12f0Douglas Gregor * 10fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor * Unless required by applicable law or agreed to in writing, software 11fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor * distributed under the License is distributed on an "AS IS" BASIS, 12fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor * See the License for the specific language governing permissions and 14debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor * limitations under the License. 150c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor */ 16debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor 17debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor//#define LOG_NDEBUG 0 18debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor#define LOG_TAG "IOMX" 19debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor#include <utils/Log.h> 20debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor 210c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor#include <sys/mman.h> 22fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor 23debc7cbc085252e68d7672d68620cfab1c714e1bDouglas Gregor#include <binder/IMemory.h> 24fa9f0a085ea5a535fa8c7f7782b39f838ceb2130Douglas Gregor#include <binder/Parcel.h> 2513529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor#include <media/IOMX.h> 260c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor#include <media/stagefright/foundation/ADebug.h> 2778d2fda9403bf61e9d2b8a0686b88d03064a12f0Douglas Gregor#include <media/openmax/OMX_IndexExt.h> 2813529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor#include <utils/NativeHandle.h> 2913529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor 3013529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregornamespace android { 3113529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor 32916033e99a497f2bd499dcf5429fc9eccf1e49eeDouglas Gregorenum { 3313529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor CONNECT = IBinder::FIRST_CALL_TRANSACTION, 3413529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor LIVES_LOCALLY, 3513529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor LIST_NODES, 3613529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor ALLOCATE_NODE, 370c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor FREE_NODE, 3813529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor SEND_COMMAND, 3913529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor GET_PARAMETER, 4013529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor SET_PARAMETER, 4113529ab3783ec557034e2fce4d4152372aaabe64Douglas Gregor GET_CONFIG, 4219a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor SET_CONFIG, 430c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor GET_STATE, 4419a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor ENABLE_NATIVE_BUFFERS, 4519a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor USE_BUFFER, 4619a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor USE_GRAPHIC_BUFFER, 4719a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor CREATE_INPUT_SURFACE, 4819a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor CREATE_PERSISTENT_INPUT_SURFACE, 490c9397b58fe69d34f3111c8ffdd450b061eab8f6Douglas Gregor SET_INPUT_SURFACE, 5019a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor SIGNAL_END_OF_INPUT_STREAM, 5119a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor STORE_META_DATA_IN_BUFFERS, 5219a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor PREPARE_FOR_ADAPTIVE_PLAYBACK, 5319a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor ALLOC_SECURE_BUFFER, 5419a2e1e609e6a9db13f649ccd9f4d1ec16aa5acdDouglas Gregor 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 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE); 818 switch (code) { 819 case GET_PARAMETER: 820 err = getParameter(node, index, params, size); 821 break; 822 case SET_PARAMETER: 823 err = setParameter(node, index, params, size); 824 break; 825 case GET_CONFIG: 826 err = getConfig(node, index, params, size); 827 break; 828 case SET_CONFIG: 829 err = setConfig(node, index, params, size); 830 break; 831 case SET_INTERNAL_OPTION: 832 { 833 InternalOptionType type = 834 (InternalOptionType)data.readInt32(); 835 836 err = setInternalOption(node, index, type, params, size); 837 break; 838 } 839 840 default: 841 TRESPASS(); 842 } 843 } 844 } 845 } else { 846 ALOGE("couldn't map: %s", strerror(errno)); 847 } 848 } 849 850 reply->writeInt32(err); 851 852 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 853 reply->write(params, size); 854 } 855 856 if (params) { 857 munmap(params, allocSize); 858 } 859 params = NULL; 860 861 return NO_ERROR; 862 } 863 864 case GET_STATE: 865 { 866 CHECK_OMX_INTERFACE(IOMX, data, reply); 867 868 node_id node = (node_id)data.readInt32(); 869 OMX_STATETYPE state = OMX_StateInvalid; 870 871 status_t err = getState(node, &state); 872 reply->writeInt32(state); 873 reply->writeInt32(err); 874 875 return NO_ERROR; 876 } 877 878 case ENABLE_NATIVE_BUFFERS: 879 { 880 CHECK_OMX_INTERFACE(IOMX, data, reply); 881 882 node_id node = (node_id)data.readInt32(); 883 OMX_U32 port_index = data.readInt32(); 884 OMX_BOOL graphic = (OMX_BOOL)data.readInt32(); 885 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 886 887 status_t err = enableNativeBuffers(node, port_index, graphic, enable); 888 reply->writeInt32(err); 889 890 return NO_ERROR; 891 } 892 893 case GET_GRAPHIC_BUFFER_USAGE: 894 { 895 CHECK_OMX_INTERFACE(IOMX, data, reply); 896 897 node_id node = (node_id)data.readInt32(); 898 OMX_U32 port_index = data.readInt32(); 899 900 OMX_U32 usage = 0; 901 status_t err = getGraphicBufferUsage(node, port_index, &usage); 902 reply->writeInt32(err); 903 reply->writeInt32(usage); 904 905 return NO_ERROR; 906 } 907 908 case USE_BUFFER: 909 { 910 CHECK_OMX_INTERFACE(IOMX, data, reply); 911 912 node_id node = (node_id)data.readInt32(); 913 OMX_U32 port_index = data.readInt32(); 914 sp<IMemory> params = 915 interface_cast<IMemory>(data.readStrongBinder()); 916 OMX_U32 allottedSize = data.readInt32(); 917 918 if (params == NULL) { 919 ALOGE("b/26392700"); 920 reply->writeInt32(INVALID_OPERATION); 921 return NO_ERROR; 922 } 923 924 buffer_id buffer; 925 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 926 reply->writeInt32(err); 927 928 if (err == OK) { 929 reply->writeInt32((int32_t)buffer); 930 } 931 932 return NO_ERROR; 933 } 934 935 case USE_GRAPHIC_BUFFER: 936 { 937 CHECK_OMX_INTERFACE(IOMX, data, reply); 938 939 node_id node = (node_id)data.readInt32(); 940 OMX_U32 port_index = data.readInt32(); 941 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 942 data.read(*graphicBuffer); 943 944 buffer_id buffer; 945 status_t err = useGraphicBuffer( 946 node, port_index, graphicBuffer, &buffer); 947 reply->writeInt32(err); 948 949 if (err == OK) { 950 reply->writeInt32((int32_t)buffer); 951 } 952 953 return NO_ERROR; 954 } 955 956 case UPDATE_GRAPHIC_BUFFER_IN_META: 957 { 958 CHECK_OMX_INTERFACE(IOMX, data, reply); 959 960 node_id node = (node_id)data.readInt32(); 961 OMX_U32 port_index = data.readInt32(); 962 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 963 data.read(*graphicBuffer); 964 buffer_id buffer = (buffer_id)data.readInt32(); 965 966 status_t err = updateGraphicBufferInMeta( 967 node, port_index, graphicBuffer, buffer); 968 reply->writeInt32(err); 969 970 return NO_ERROR; 971 } 972 973 case UPDATE_NATIVE_HANDLE_IN_META: 974 { 975 CHECK_OMX_INTERFACE(IOMX, data, reply); 976 977 node_id node = (node_id)data.readInt32(); 978 OMX_U32 port_index = data.readInt32(); 979 native_handle *handle = NULL; 980 if (data.readInt32()) { 981 handle = data.readNativeHandle(); 982 } 983 buffer_id buffer = (buffer_id)data.readInt32(); 984 985 status_t err = updateNativeHandleInMeta( 986 node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer); 987 reply->writeInt32(err); 988 989 return NO_ERROR; 990 } 991 992 case CREATE_INPUT_SURFACE: 993 { 994 CHECK_OMX_INTERFACE(IOMX, data, reply); 995 996 node_id node = (node_id)data.readInt32(); 997 OMX_U32 port_index = data.readInt32(); 998 android_dataspace dataSpace = (android_dataspace)data.readInt32(); 999 1000 sp<IGraphicBufferProducer> bufferProducer; 1001 MetadataBufferType type = kMetadataBufferTypeInvalid; 1002 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type); 1003 1004 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 1005 android_errorWriteLog(0x534e4554, "26324358"); 1006 } 1007 1008 reply->writeInt32(type); 1009 reply->writeInt32(err); 1010 1011 if (err == OK) { 1012 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 1013 } 1014 1015 return NO_ERROR; 1016 } 1017 1018 case CREATE_PERSISTENT_INPUT_SURFACE: 1019 { 1020 CHECK_OMX_INTERFACE(IOMX, data, reply); 1021 1022 sp<IGraphicBufferProducer> bufferProducer; 1023 sp<IGraphicBufferConsumer> bufferConsumer; 1024 status_t err = createPersistentInputSurface( 1025 &bufferProducer, &bufferConsumer); 1026 1027 reply->writeInt32(err); 1028 1029 if (err == OK) { 1030 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 1031 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 1032 } 1033 1034 return NO_ERROR; 1035 } 1036 1037 case SET_INPUT_SURFACE: 1038 { 1039 CHECK_OMX_INTERFACE(IOMX, data, reply); 1040 1041 node_id node = (node_id)data.readInt32(); 1042 OMX_U32 port_index = data.readInt32(); 1043 1044 sp<IGraphicBufferConsumer> bufferConsumer = 1045 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 1046 1047 MetadataBufferType type = kMetadataBufferTypeInvalid; 1048 1049 status_t err = INVALID_OPERATION; 1050 if (bufferConsumer == NULL) { 1051 ALOGE("b/26392700"); 1052 } else { 1053 err = setInputSurface(node, port_index, bufferConsumer, &type); 1054 1055 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 1056 android_errorWriteLog(0x534e4554, "26324358"); 1057 } 1058 } 1059 1060 reply->writeInt32(type); 1061 reply->writeInt32(err); 1062 return NO_ERROR; 1063 } 1064 1065 case SIGNAL_END_OF_INPUT_STREAM: 1066 { 1067 CHECK_OMX_INTERFACE(IOMX, data, reply); 1068 1069 node_id node = (node_id)data.readInt32(); 1070 1071 status_t err = signalEndOfInputStream(node); 1072 reply->writeInt32(err); 1073 1074 return NO_ERROR; 1075 } 1076 1077 case STORE_META_DATA_IN_BUFFERS: 1078 { 1079 CHECK_OMX_INTERFACE(IOMX, data, reply); 1080 1081 node_id node = (node_id)data.readInt32(); 1082 OMX_U32 port_index = data.readInt32(); 1083 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1084 1085 MetadataBufferType type = (MetadataBufferType)data.readInt32(); 1086 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 1087 1088 reply->writeInt32(type); 1089 reply->writeInt32(err); 1090 1091 return NO_ERROR; 1092 } 1093 1094 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 1095 { 1096 CHECK_OMX_INTERFACE(IOMX, data, reply); 1097 1098 node_id node = (node_id)data.readInt32(); 1099 OMX_U32 port_index = data.readInt32(); 1100 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1101 OMX_U32 max_width = data.readInt32(); 1102 OMX_U32 max_height = data.readInt32(); 1103 1104 status_t err = prepareForAdaptivePlayback( 1105 node, port_index, enable, max_width, max_height); 1106 reply->writeInt32(err); 1107 1108 return NO_ERROR; 1109 } 1110 1111 case CONFIGURE_VIDEO_TUNNEL_MODE: 1112 { 1113 CHECK_OMX_INTERFACE(IOMX, data, reply); 1114 1115 node_id node = (node_id)data.readInt32(); 1116 OMX_U32 port_index = data.readInt32(); 1117 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 1118 OMX_U32 audio_hw_sync = data.readInt32(); 1119 1120 native_handle_t *sideband_handle = NULL; 1121 status_t err = configureVideoTunnelMode( 1122 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 1123 reply->writeInt32(err); 1124 if(err == OK){ 1125 reply->writeNativeHandle(sideband_handle); 1126 } 1127 1128 return NO_ERROR; 1129 } 1130 1131 case ALLOC_SECURE_BUFFER: 1132 { 1133 CHECK_OMX_INTERFACE(IOMX, data, reply); 1134 1135 node_id node = (node_id)data.readInt32(); 1136 OMX_U32 port_index = data.readInt32(); 1137 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 1138 ALOGE("b/24310423"); 1139 reply->writeInt32(INVALID_OPERATION); 1140 return NO_ERROR; 1141 } 1142 1143 size_t size = data.readInt64(); 1144 1145 buffer_id buffer; 1146 void *buffer_data = NULL; 1147 sp<NativeHandle> native_handle; 1148 status_t err = allocateSecureBuffer( 1149 node, port_index, size, &buffer, &buffer_data, &native_handle); 1150 reply->writeInt32(err); 1151 1152 if (err == OK) { 1153 reply->writeInt32((int32_t)buffer); 1154 reply->writeInt64((uintptr_t)buffer_data); 1155 if (buffer_data == NULL) { 1156 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle()); 1157 } 1158 } 1159 1160 return NO_ERROR; 1161 } 1162 1163 case ALLOC_BUFFER_WITH_BACKUP: 1164 { 1165 CHECK_OMX_INTERFACE(IOMX, data, reply); 1166 1167 node_id node = (node_id)data.readInt32(); 1168 OMX_U32 port_index = data.readInt32(); 1169 sp<IMemory> params = 1170 interface_cast<IMemory>(data.readStrongBinder()); 1171 OMX_U32 allottedSize = data.readInt32(); 1172 1173 if (params == NULL) { 1174 ALOGE("b/26392700"); 1175 reply->writeInt32(INVALID_OPERATION); 1176 return NO_ERROR; 1177 } 1178 1179 buffer_id buffer; 1180 status_t err = allocateBufferWithBackup( 1181 node, port_index, params, &buffer, allottedSize); 1182 1183 reply->writeInt32(err); 1184 1185 if (err == OK) { 1186 reply->writeInt32((int32_t)buffer); 1187 } 1188 1189 return NO_ERROR; 1190 } 1191 1192 case FREE_BUFFER: 1193 { 1194 CHECK_OMX_INTERFACE(IOMX, data, reply); 1195 1196 node_id node = (node_id)data.readInt32(); 1197 OMX_U32 port_index = data.readInt32(); 1198 buffer_id buffer = (buffer_id)data.readInt32(); 1199 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1200 1201 return NO_ERROR; 1202 } 1203 1204 case FILL_BUFFER: 1205 { 1206 CHECK_OMX_INTERFACE(IOMX, data, reply); 1207 1208 node_id node = (node_id)data.readInt32(); 1209 buffer_id buffer = (buffer_id)data.readInt32(); 1210 bool haveFence = data.readInt32(); 1211 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1212 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1213 1214 return NO_ERROR; 1215 } 1216 1217 case EMPTY_BUFFER: 1218 { 1219 CHECK_OMX_INTERFACE(IOMX, data, reply); 1220 1221 node_id node = (node_id)data.readInt32(); 1222 buffer_id buffer = (buffer_id)data.readInt32(); 1223 OMX_U32 range_offset = data.readInt32(); 1224 OMX_U32 range_length = data.readInt32(); 1225 OMX_U32 flags = data.readInt32(); 1226 OMX_TICKS timestamp = data.readInt64(); 1227 bool haveFence = data.readInt32(); 1228 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1229 reply->writeInt32(emptyBuffer( 1230 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1231 1232 return NO_ERROR; 1233 } 1234 1235 case EMPTY_GRAPHIC_BUFFER: 1236 { 1237 CHECK_OMX_INTERFACE(IOMX, data, reply); 1238 1239 node_id node = (node_id)data.readInt32(); 1240 buffer_id buffer = (buffer_id)data.readInt32(); 1241 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 1242 data.read(*graphicBuffer); 1243 OMX_U32 flags = data.readInt32(); 1244 OMX_TICKS timestamp = data.readInt64(); 1245 bool haveFence = data.readInt32(); 1246 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1247 reply->writeInt32(emptyGraphicBuffer( 1248 node, buffer, graphicBuffer, flags, timestamp, fenceFd)); 1249 1250 return NO_ERROR; 1251 } 1252 1253 case GET_EXTENSION_INDEX: 1254 { 1255 CHECK_OMX_INTERFACE(IOMX, data, reply); 1256 1257 node_id node = (node_id)data.readInt32(); 1258 const char *parameter_name = data.readCString(); 1259 1260 if (parameter_name == NULL) { 1261 ALOGE("b/26392700"); 1262 reply->writeInt32(INVALID_OPERATION); 1263 return NO_ERROR; 1264 } 1265 1266 OMX_INDEXTYPE index; 1267 status_t err = getExtensionIndex(node, parameter_name, &index); 1268 1269 reply->writeInt32(err); 1270 1271 if (err == OK) { 1272 reply->writeInt32(index); 1273 } 1274 1275 return OK; 1276 } 1277 1278 case DISPATCH_MESSAGE: 1279 { 1280 CHECK_OMX_INTERFACE(IOMX, data, reply); 1281 omx_message msg; 1282 msg.node = data.readInt32(); 1283 int haveFence = data.readInt32(); 1284 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1285 msg.type = (typeof(msg.type))data.readInt32(); 1286 status_t err = data.read(&msg.u, sizeof(msg.u)); 1287 1288 if (err == OK) { 1289 err = dispatchMessage(msg); 1290 } 1291 reply->writeInt32(err); 1292 1293 return NO_ERROR; 1294 } 1295 1296 default: 1297 return BBinder::onTransact(code, data, reply, flags); 1298 } 1299} 1300 1301//////////////////////////////////////////////////////////////////////////////// 1302 1303class BpOMXObserver : public BpInterface<IOMXObserver> { 1304public: 1305 explicit BpOMXObserver(const sp<IBinder> &impl) 1306 : BpInterface<IOMXObserver>(impl) { 1307 } 1308 1309 virtual void onMessages(const std::list<omx_message> &messages) { 1310 Parcel data, reply; 1311 std::list<omx_message>::const_iterator it = messages.cbegin(); 1312 bool first = true; 1313 while (it != messages.cend()) { 1314 const omx_message &msg = *it++; 1315 if (first) { 1316 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1317 data.writeInt32(msg.node); 1318 first = false; 1319 } 1320 data.writeInt32(msg.fenceFd >= 0); 1321 if (msg.fenceFd >= 0) { 1322 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1323 } 1324 data.writeInt32(msg.type); 1325 data.write(&msg.u, sizeof(msg.u)); 1326 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1327 } 1328 if (!first) { 1329 data.writeInt32(-1); // mark end 1330 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1331 } 1332 } 1333}; 1334 1335IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1336 1337status_t BnOMXObserver::onTransact( 1338 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1339 switch (code) { 1340 case OBSERVER_ON_MSG: 1341 { 1342 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1343 IOMX::node_id node = data.readInt32(); 1344 std::list<omx_message> messages; 1345 status_t err = FAILED_TRANSACTION; // must receive at least one message 1346 do { 1347 int haveFence = data.readInt32(); 1348 if (haveFence < 0) { // we use -1 to mark end of messages 1349 break; 1350 } 1351 omx_message msg; 1352 msg.node = node; 1353 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1354 msg.type = (typeof(msg.type))data.readInt32(); 1355 err = data.read(&msg.u, sizeof(msg.u)); 1356 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1357 messages.push_back(msg); 1358 } while (err == OK); 1359 1360 if (err == OK) { 1361 onMessages(messages); 1362 } 1363 1364 return err; 1365 } 1366 1367 default: 1368 return BBinder::onTransact(code, data, reply, flags); 1369 } 1370} 1371 1372} // namespace android 1373