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