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