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