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