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:
BpOMX(const sp<IBinder> & impl)69     BpOMX(const sp<IBinder> &impl)
70         : BpInterface<IOMX>(impl) {
71     }
72 
livesLocally(node_id node,pid_t pid)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 
listNodes(List<ComponentInfo> * list)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 
allocateNode(const char * name,const sp<IOMXObserver> & observer,sp<IBinder> * nodeBinder,node_id * node)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 
freeNode(node_id node)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 
sendCommand(node_id node,OMX_COMMANDTYPE cmd,OMX_S32 param)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 
getParameter(node_id node,OMX_INDEXTYPE index,void * params,size_t size)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 
setParameter(node_id node,OMX_INDEXTYPE index,const void * params,size_t size)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 
getConfig(node_id node,OMX_INDEXTYPE index,void * params,size_t size)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 
setConfig(node_id node,OMX_INDEXTYPE index,const void * params,size_t size)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 
getState(node_id node,OMX_STATETYPE * state)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 
enableNativeBuffers(node_id node,OMX_U32 port_index,OMX_BOOL graphic,OMX_BOOL enable)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 
getGraphicBufferUsage(node_id node,OMX_U32 port_index,OMX_U32 * usage)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 
useBuffer(node_id node,OMX_U32 port_index,const sp<IMemory> & params,buffer_id * buffer,OMX_U32 allottedSize)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 
useGraphicBuffer(node_id node,OMX_U32 port_index,const sp<GraphicBuffer> & graphicBuffer,buffer_id * buffer)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 
updateGraphicBufferInMeta(node_id node,OMX_U32 port_index,const sp<GraphicBuffer> & graphicBuffer,buffer_id buffer)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 
updateNativeHandleInMeta(node_id node,OMX_U32 port_index,const sp<NativeHandle> & nativeHandle,buffer_id buffer)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 
createInputSurface(node_id node,OMX_U32 port_index,android_dataspace dataSpace,sp<IGraphicBufferProducer> * bufferProducer,MetadataBufferType * type)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 
createPersistentInputSurface(sp<IGraphicBufferProducer> * bufferProducer,sp<IGraphicBufferConsumer> * bufferConsumer)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 
setInputSurface(node_id node,OMX_U32 port_index,const sp<IGraphicBufferConsumer> & bufferConsumer,MetadataBufferType * type)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 
signalEndOfInputStream(node_id node)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 
storeMetaDataInBuffers(node_id node,OMX_U32 port_index,OMX_BOOL enable,MetadataBufferType * type)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 
prepareForAdaptivePlayback(node_id node,OMX_U32 port_index,OMX_BOOL enable,OMX_U32 max_width,OMX_U32 max_height)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 
configureVideoTunnelMode(node_id node,OMX_U32 portIndex,OMX_BOOL tunneled,OMX_U32 audioHwSync,native_handle_t ** sidebandHandle)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 
allocateSecureBuffer(node_id node,OMX_U32 port_index,size_t size,buffer_id * buffer,void ** buffer_data,sp<NativeHandle> * native_handle)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 
allocateBufferWithBackup(node_id node,OMX_U32 port_index,const sp<IMemory> & params,buffer_id * buffer,OMX_U32 allottedSize)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 
freeBuffer(node_id node,OMX_U32 port_index,buffer_id buffer)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 
fillBuffer(node_id node,buffer_id buffer,int fenceFd)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 
emptyBuffer(node_id node,buffer_id buffer,OMX_U32 range_offset,OMX_U32 range_length,OMX_U32 flags,OMX_TICKS timestamp,int fenceFd)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 
getExtensionIndex(node_id node,const char * parameter_name,OMX_INDEXTYPE * index)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 
setInternalOption(node_id node,OMX_U32 port_index,InternalOptionType type,const void * optionData,size_t size)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 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)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                             mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
779                             switch (code) {
780                                 case GET_PARAMETER:
781                                     err = getParameter(node, index, params, size);
782                                     break;
783                                 case SET_PARAMETER:
784                                     err = setParameter(node, index, params, size);
785                                     break;
786                                 case GET_CONFIG:
787                                     err = getConfig(node, index, params, size);
788                                     break;
789                                 case SET_CONFIG:
790                                     err = setConfig(node, index, params, size);
791                                     break;
792                                 case SET_INTERNAL_OPTION:
793                                 {
794                                     InternalOptionType type =
795                                         (InternalOptionType)data.readInt32();
796 
797                                     err = setInternalOption(node, index, type, params, size);
798                                     break;
799                                 }
800 
801                                 default:
802                                     TRESPASS();
803                             }
804                         }
805                     }
806                 } else {
807                     ALOGE("couldn't map: %s", strerror(errno));
808                 }
809             }
810 
811             reply->writeInt32(err);
812 
813             if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
814                 reply->write(params, size);
815             }
816 
817             if (params) {
818                 munmap(params, allocSize);
819             }
820             params = NULL;
821 
822             return NO_ERROR;
823         }
824 
825         case GET_STATE:
826         {
827             CHECK_OMX_INTERFACE(IOMX, data, reply);
828 
829             node_id node = (node_id)data.readInt32();
830             OMX_STATETYPE state = OMX_StateInvalid;
831 
832             status_t err = getState(node, &state);
833             reply->writeInt32(state);
834             reply->writeInt32(err);
835 
836             return NO_ERROR;
837         }
838 
839         case ENABLE_NATIVE_BUFFERS:
840         {
841             CHECK_OMX_INTERFACE(IOMX, data, reply);
842 
843             node_id node = (node_id)data.readInt32();
844             OMX_U32 port_index = data.readInt32();
845             OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
846             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
847 
848             status_t err = enableNativeBuffers(node, port_index, graphic, enable);
849             reply->writeInt32(err);
850 
851             return NO_ERROR;
852         }
853 
854         case GET_GRAPHIC_BUFFER_USAGE:
855         {
856             CHECK_OMX_INTERFACE(IOMX, data, reply);
857 
858             node_id node = (node_id)data.readInt32();
859             OMX_U32 port_index = data.readInt32();
860 
861             OMX_U32 usage = 0;
862             status_t err = getGraphicBufferUsage(node, port_index, &usage);
863             reply->writeInt32(err);
864             reply->writeInt32(usage);
865 
866             return NO_ERROR;
867         }
868 
869         case USE_BUFFER:
870         {
871             CHECK_OMX_INTERFACE(IOMX, data, reply);
872 
873             node_id node = (node_id)data.readInt32();
874             OMX_U32 port_index = data.readInt32();
875             sp<IMemory> params =
876                 interface_cast<IMemory>(data.readStrongBinder());
877             OMX_U32 allottedSize = data.readInt32();
878 
879             if (params == NULL) {
880                 ALOGE("b/26392700");
881                 reply->writeInt32(INVALID_OPERATION);
882                 return NO_ERROR;
883             }
884 
885             buffer_id buffer;
886             status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
887             reply->writeInt32(err);
888 
889             if (err == OK) {
890                 reply->writeInt32((int32_t)buffer);
891             }
892 
893             return NO_ERROR;
894         }
895 
896         case USE_GRAPHIC_BUFFER:
897         {
898             CHECK_OMX_INTERFACE(IOMX, data, reply);
899 
900             node_id node = (node_id)data.readInt32();
901             OMX_U32 port_index = data.readInt32();
902             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
903             data.read(*graphicBuffer);
904 
905             buffer_id buffer;
906             status_t err = useGraphicBuffer(
907                     node, port_index, graphicBuffer, &buffer);
908             reply->writeInt32(err);
909 
910             if (err == OK) {
911                 reply->writeInt32((int32_t)buffer);
912             }
913 
914             return NO_ERROR;
915         }
916 
917         case UPDATE_GRAPHIC_BUFFER_IN_META:
918         {
919             CHECK_OMX_INTERFACE(IOMX, data, reply);
920 
921             node_id node = (node_id)data.readInt32();
922             OMX_U32 port_index = data.readInt32();
923             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
924             data.read(*graphicBuffer);
925             buffer_id buffer = (buffer_id)data.readInt32();
926 
927             status_t err = updateGraphicBufferInMeta(
928                     node, port_index, graphicBuffer, buffer);
929             reply->writeInt32(err);
930 
931             return NO_ERROR;
932         }
933 
934         case UPDATE_NATIVE_HANDLE_IN_META:
935         {
936             CHECK_OMX_INTERFACE(IOMX, data, reply);
937 
938             node_id node = (node_id)data.readInt32();
939             OMX_U32 port_index = data.readInt32();
940             native_handle *handle = NULL;
941             if (data.readInt32()) {
942                 handle = data.readNativeHandle();
943             }
944             buffer_id buffer = (buffer_id)data.readInt32();
945 
946             status_t err = updateNativeHandleInMeta(
947                     node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
948             reply->writeInt32(err);
949 
950             return NO_ERROR;
951         }
952 
953         case CREATE_INPUT_SURFACE:
954         {
955             CHECK_OMX_INTERFACE(IOMX, data, reply);
956 
957             node_id node = (node_id)data.readInt32();
958             OMX_U32 port_index = data.readInt32();
959             android_dataspace dataSpace = (android_dataspace)data.readInt32();
960 
961             sp<IGraphicBufferProducer> bufferProducer;
962             MetadataBufferType type = kMetadataBufferTypeInvalid;
963             status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type);
964 
965             if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
966                 android_errorWriteLog(0x534e4554, "26324358");
967             }
968 
969             reply->writeInt32(type);
970             reply->writeInt32(err);
971 
972             if (err == OK) {
973                 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
974             }
975 
976             return NO_ERROR;
977         }
978 
979         case CREATE_PERSISTENT_INPUT_SURFACE:
980         {
981             CHECK_OMX_INTERFACE(IOMX, data, reply);
982 
983             sp<IGraphicBufferProducer> bufferProducer;
984             sp<IGraphicBufferConsumer> bufferConsumer;
985             status_t err = createPersistentInputSurface(
986                     &bufferProducer, &bufferConsumer);
987 
988             reply->writeInt32(err);
989 
990             if (err == OK) {
991                 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
992                 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
993             }
994 
995             return NO_ERROR;
996         }
997 
998         case SET_INPUT_SURFACE:
999         {
1000             CHECK_OMX_INTERFACE(IOMX, data, reply);
1001 
1002             node_id node = (node_id)data.readInt32();
1003             OMX_U32 port_index = data.readInt32();
1004 
1005             sp<IGraphicBufferConsumer> bufferConsumer =
1006                     interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
1007 
1008             MetadataBufferType type = kMetadataBufferTypeInvalid;
1009 
1010             status_t err = INVALID_OPERATION;
1011             if (bufferConsumer == NULL) {
1012                 ALOGE("b/26392700");
1013             } else {
1014                 err = setInputSurface(node, port_index, bufferConsumer, &type);
1015 
1016                 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
1017                    android_errorWriteLog(0x534e4554, "26324358");
1018                 }
1019             }
1020 
1021             reply->writeInt32(type);
1022             reply->writeInt32(err);
1023             return NO_ERROR;
1024         }
1025 
1026         case SIGNAL_END_OF_INPUT_STREAM:
1027         {
1028             CHECK_OMX_INTERFACE(IOMX, data, reply);
1029 
1030             node_id node = (node_id)data.readInt32();
1031 
1032             status_t err = signalEndOfInputStream(node);
1033             reply->writeInt32(err);
1034 
1035             return NO_ERROR;
1036         }
1037 
1038         case STORE_META_DATA_IN_BUFFERS:
1039         {
1040             CHECK_OMX_INTERFACE(IOMX, data, reply);
1041 
1042             node_id node = (node_id)data.readInt32();
1043             OMX_U32 port_index = data.readInt32();
1044             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1045 
1046             MetadataBufferType type = (MetadataBufferType)data.readInt32();
1047             status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
1048 
1049             reply->writeInt32(type);
1050             reply->writeInt32(err);
1051 
1052             return NO_ERROR;
1053         }
1054 
1055         case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1056         {
1057             CHECK_OMX_INTERFACE(IOMX, data, reply);
1058 
1059             node_id node = (node_id)data.readInt32();
1060             OMX_U32 port_index = data.readInt32();
1061             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1062             OMX_U32 max_width = data.readInt32();
1063             OMX_U32 max_height = data.readInt32();
1064 
1065             status_t err = prepareForAdaptivePlayback(
1066                     node, port_index, enable, max_width, max_height);
1067             reply->writeInt32(err);
1068 
1069             return NO_ERROR;
1070         }
1071 
1072         case CONFIGURE_VIDEO_TUNNEL_MODE:
1073         {
1074             CHECK_OMX_INTERFACE(IOMX, data, reply);
1075 
1076             node_id node = (node_id)data.readInt32();
1077             OMX_U32 port_index = data.readInt32();
1078             OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1079             OMX_U32 audio_hw_sync = data.readInt32();
1080 
1081             native_handle_t *sideband_handle = NULL;
1082             status_t err = configureVideoTunnelMode(
1083                     node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1084             reply->writeInt32(err);
1085             if(err == OK){
1086                 reply->writeNativeHandle(sideband_handle);
1087             }
1088 
1089             return NO_ERROR;
1090         }
1091 
1092         case ALLOC_SECURE_BUFFER:
1093         {
1094             CHECK_OMX_INTERFACE(IOMX, data, reply);
1095 
1096             node_id node = (node_id)data.readInt32();
1097             OMX_U32 port_index = data.readInt32();
1098             if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1099                 ALOGE("b/24310423");
1100                 reply->writeInt32(INVALID_OPERATION);
1101                 return NO_ERROR;
1102             }
1103 
1104             size_t size = data.readInt64();
1105 
1106             buffer_id buffer;
1107             void *buffer_data = NULL;
1108             sp<NativeHandle> native_handle;
1109             status_t err = allocateSecureBuffer(
1110                     node, port_index, size, &buffer, &buffer_data, &native_handle);
1111             reply->writeInt32(err);
1112 
1113             if (err == OK) {
1114                 reply->writeInt32((int32_t)buffer);
1115                 reply->writeInt64((uintptr_t)buffer_data);
1116                 if (buffer_data == NULL) {
1117                     reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
1118                 }
1119             }
1120 
1121             return NO_ERROR;
1122         }
1123 
1124         case ALLOC_BUFFER_WITH_BACKUP:
1125         {
1126             CHECK_OMX_INTERFACE(IOMX, data, reply);
1127 
1128             node_id node = (node_id)data.readInt32();
1129             OMX_U32 port_index = data.readInt32();
1130             sp<IMemory> params =
1131                 interface_cast<IMemory>(data.readStrongBinder());
1132             OMX_U32 allottedSize = data.readInt32();
1133 
1134             if (params == NULL) {
1135                 ALOGE("b/26392700");
1136                 reply->writeInt32(INVALID_OPERATION);
1137                 return NO_ERROR;
1138             }
1139 
1140             buffer_id buffer;
1141             status_t err = allocateBufferWithBackup(
1142                     node, port_index, params, &buffer, allottedSize);
1143 
1144             reply->writeInt32(err);
1145 
1146             if (err == OK) {
1147                 reply->writeInt32((int32_t)buffer);
1148             }
1149 
1150             return NO_ERROR;
1151         }
1152 
1153         case FREE_BUFFER:
1154         {
1155             CHECK_OMX_INTERFACE(IOMX, data, reply);
1156 
1157             node_id node = (node_id)data.readInt32();
1158             OMX_U32 port_index = data.readInt32();
1159             buffer_id buffer = (buffer_id)data.readInt32();
1160             reply->writeInt32(freeBuffer(node, port_index, buffer));
1161 
1162             return NO_ERROR;
1163         }
1164 
1165         case FILL_BUFFER:
1166         {
1167             CHECK_OMX_INTERFACE(IOMX, data, reply);
1168 
1169             node_id node = (node_id)data.readInt32();
1170             buffer_id buffer = (buffer_id)data.readInt32();
1171             bool haveFence = data.readInt32();
1172             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1173             reply->writeInt32(fillBuffer(node, buffer, fenceFd));
1174 
1175             return NO_ERROR;
1176         }
1177 
1178         case EMPTY_BUFFER:
1179         {
1180             CHECK_OMX_INTERFACE(IOMX, data, reply);
1181 
1182             node_id node = (node_id)data.readInt32();
1183             buffer_id buffer = (buffer_id)data.readInt32();
1184             OMX_U32 range_offset = data.readInt32();
1185             OMX_U32 range_length = data.readInt32();
1186             OMX_U32 flags = data.readInt32();
1187             OMX_TICKS timestamp = data.readInt64();
1188             bool haveFence = data.readInt32();
1189             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1190             reply->writeInt32(emptyBuffer(
1191                     node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
1192 
1193             return NO_ERROR;
1194         }
1195 
1196         case GET_EXTENSION_INDEX:
1197         {
1198             CHECK_OMX_INTERFACE(IOMX, data, reply);
1199 
1200             node_id node = (node_id)data.readInt32();
1201             const char *parameter_name = data.readCString();
1202 
1203             if (parameter_name == NULL) {
1204                 ALOGE("b/26392700");
1205                 reply->writeInt32(INVALID_OPERATION);
1206                 return NO_ERROR;
1207             }
1208 
1209             OMX_INDEXTYPE index;
1210             status_t err = getExtensionIndex(node, parameter_name, &index);
1211 
1212             reply->writeInt32(err);
1213 
1214             if (err == OK) {
1215                 reply->writeInt32(index);
1216             }
1217 
1218             return OK;
1219         }
1220 
1221         default:
1222             return BBinder::onTransact(code, data, reply, flags);
1223     }
1224 }
1225 
1226 ////////////////////////////////////////////////////////////////////////////////
1227 
1228 class BpOMXObserver : public BpInterface<IOMXObserver> {
1229 public:
BpOMXObserver(const sp<IBinder> & impl)1230     BpOMXObserver(const sp<IBinder> &impl)
1231         : BpInterface<IOMXObserver>(impl) {
1232     }
1233 
onMessages(const std::list<omx_message> & messages)1234     virtual void onMessages(const std::list<omx_message> &messages) {
1235         Parcel data, reply;
1236         std::list<omx_message>::const_iterator it = messages.cbegin();
1237         bool first = true;
1238         while (it != messages.cend()) {
1239             const omx_message &msg = *it++;
1240             if (first) {
1241                 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1242                 data.writeInt32(msg.node);
1243                 first = false;
1244             }
1245             data.writeInt32(msg.fenceFd >= 0);
1246             if (msg.fenceFd >= 0) {
1247                 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1248             }
1249             data.writeInt32(msg.type);
1250             data.write(&msg.u, sizeof(msg.u));
1251             ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
1252         }
1253         if (!first) {
1254             data.writeInt32(-1); // mark end
1255             remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1256         }
1257     }
1258 };
1259 
1260 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1261 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1262 status_t BnOMXObserver::onTransact(
1263     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1264     switch (code) {
1265         case OBSERVER_ON_MSG:
1266         {
1267             CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
1268             IOMX::node_id node = data.readInt32();
1269             std::list<omx_message> messages;
1270             status_t err = FAILED_TRANSACTION; // must receive at least one message
1271             do {
1272                 int haveFence = data.readInt32();
1273                 if (haveFence < 0) { // we use -1 to mark end of messages
1274                     break;
1275                 }
1276                 omx_message msg;
1277                 msg.node = node;
1278                 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1279                 msg.type = (typeof(msg.type))data.readInt32();
1280                 err = data.read(&msg.u, sizeof(msg.u));
1281                 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1282                 messages.push_back(msg);
1283             } while (err == OK);
1284 
1285             if (err == OK) {
1286                 onMessages(messages);
1287             }
1288 
1289             return err;
1290         }
1291 
1292         default:
1293             return BBinder::onTransact(code, data, reply, flags);
1294     }
1295 }
1296 
1297 }  // namespace android
1298