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