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