[go: nahoru, domu]

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                            mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
779                            switch (code) {
780                                case GET_PARAMETER:
781                                    err = getParameter(node, index, params, size);
782                                    break;
783                                case SET_PARAMETER:
784                                    err = setParameter(node, index, params, size);
785                                    break;
786                                case GET_CONFIG:
787                                    err = getConfig(node, index, params, size);
788                                    break;
789                                case SET_CONFIG:
790                                    err = setConfig(node, index, params, size);
791                                    break;
792                                case SET_INTERNAL_OPTION:
793                                {
794                                    InternalOptionType type =
795                                        (InternalOptionType)data.readInt32();
796
797                                    err = setInternalOption(node, index, type, params, size);
798                                    break;
799                                }
800
801                                default:
802                                    TRESPASS();
803                            }
804                        }
805                    }
806                } else {
807                    ALOGE("couldn't map: %s", strerror(errno));
808                }
809            }
810
811            reply->writeInt32(err);
812
813            if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
814                reply->write(params, size);
815            }
816
817            if (params) {
818                munmap(params, allocSize);
819            }
820            params = NULL;
821
822            return NO_ERROR;
823        }
824
825        case GET_STATE:
826        {
827            CHECK_OMX_INTERFACE(IOMX, data, reply);
828
829            node_id node = (node_id)data.readInt32();
830            OMX_STATETYPE state = OMX_StateInvalid;
831
832            status_t err = getState(node, &state);
833            reply->writeInt32(state);
834            reply->writeInt32(err);
835
836            return NO_ERROR;
837        }
838
839        case ENABLE_NATIVE_BUFFERS:
840        {
841            CHECK_OMX_INTERFACE(IOMX, data, reply);
842
843            node_id node = (node_id)data.readInt32();
844            OMX_U32 port_index = data.readInt32();
845            OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
846            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
847
848            status_t err = enableNativeBuffers(node, port_index, graphic, enable);
849            reply->writeInt32(err);
850
851            return NO_ERROR;
852        }
853
854        case GET_GRAPHIC_BUFFER_USAGE:
855        {
856            CHECK_OMX_INTERFACE(IOMX, data, reply);
857
858            node_id node = (node_id)data.readInt32();
859            OMX_U32 port_index = data.readInt32();
860
861            OMX_U32 usage = 0;
862            status_t err = getGraphicBufferUsage(node, port_index, &usage);
863            reply->writeInt32(err);
864            reply->writeInt32(usage);
865
866            return NO_ERROR;
867        }
868
869        case USE_BUFFER:
870        {
871            CHECK_OMX_INTERFACE(IOMX, data, reply);
872
873            node_id node = (node_id)data.readInt32();
874            OMX_U32 port_index = data.readInt32();
875            sp<IMemory> params =
876                interface_cast<IMemory>(data.readStrongBinder());
877            OMX_U32 allottedSize = data.readInt32();
878
879            if (params == NULL) {
880                ALOGE("b/26392700");
881                reply->writeInt32(INVALID_OPERATION);
882                return NO_ERROR;
883            }
884
885            buffer_id buffer;
886            status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
887            reply->writeInt32(err);
888
889            if (err == OK) {
890                reply->writeInt32((int32_t)buffer);
891            }
892
893            return NO_ERROR;
894        }
895
896        case USE_GRAPHIC_BUFFER:
897        {
898            CHECK_OMX_INTERFACE(IOMX, data, reply);
899
900            node_id node = (node_id)data.readInt32();
901            OMX_U32 port_index = data.readInt32();
902            sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
903            data.read(*graphicBuffer);
904
905            buffer_id buffer;
906            status_t err = useGraphicBuffer(
907                    node, port_index, graphicBuffer, &buffer);
908            reply->writeInt32(err);
909
910            if (err == OK) {
911                reply->writeInt32((int32_t)buffer);
912            }
913
914            return NO_ERROR;
915        }
916
917        case UPDATE_GRAPHIC_BUFFER_IN_META:
918        {
919            CHECK_OMX_INTERFACE(IOMX, data, reply);
920
921            node_id node = (node_id)data.readInt32();
922            OMX_U32 port_index = data.readInt32();
923            sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
924            data.read(*graphicBuffer);
925            buffer_id buffer = (buffer_id)data.readInt32();
926
927            status_t err = updateGraphicBufferInMeta(
928                    node, port_index, graphicBuffer, buffer);
929            reply->writeInt32(err);
930
931            return NO_ERROR;
932        }
933
934        case UPDATE_NATIVE_HANDLE_IN_META:
935        {
936            CHECK_OMX_INTERFACE(IOMX, data, reply);
937
938            node_id node = (node_id)data.readInt32();
939            OMX_U32 port_index = data.readInt32();
940            native_handle *handle = NULL;
941            if (data.readInt32()) {
942                handle = data.readNativeHandle();
943            }
944            buffer_id buffer = (buffer_id)data.readInt32();
945
946            status_t err = updateNativeHandleInMeta(
947                    node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
948            reply->writeInt32(err);
949
950            return NO_ERROR;
951        }
952
953        case CREATE_INPUT_SURFACE:
954        {
955            CHECK_OMX_INTERFACE(IOMX, data, reply);
956
957            node_id node = (node_id)data.readInt32();
958            OMX_U32 port_index = data.readInt32();
959            android_dataspace dataSpace = (android_dataspace)data.readInt32();
960
961            sp<IGraphicBufferProducer> bufferProducer;
962            MetadataBufferType type = kMetadataBufferTypeInvalid;
963            status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type);
964
965            if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
966                android_errorWriteLog(0x534e4554, "26324358");
967            }
968
969            reply->writeInt32(type);
970            reply->writeInt32(err);
971
972            if (err == OK) {
973                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
974            }
975
976            return NO_ERROR;
977        }
978
979        case CREATE_PERSISTENT_INPUT_SURFACE:
980        {
981            CHECK_OMX_INTERFACE(IOMX, data, reply);
982
983            sp<IGraphicBufferProducer> bufferProducer;
984            sp<IGraphicBufferConsumer> bufferConsumer;
985            status_t err = createPersistentInputSurface(
986                    &bufferProducer, &bufferConsumer);
987
988            reply->writeInt32(err);
989
990            if (err == OK) {
991                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
992                reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
993            }
994
995            return NO_ERROR;
996        }
997
998        case SET_INPUT_SURFACE:
999        {
1000            CHECK_OMX_INTERFACE(IOMX, data, reply);
1001
1002            node_id node = (node_id)data.readInt32();
1003            OMX_U32 port_index = data.readInt32();
1004
1005            sp<IGraphicBufferConsumer> bufferConsumer =
1006                    interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
1007
1008            MetadataBufferType type = kMetadataBufferTypeInvalid;
1009
1010            status_t err = INVALID_OPERATION;
1011            if (bufferConsumer == NULL) {
1012                ALOGE("b/26392700");
1013            } else {
1014                err = setInputSurface(node, port_index, bufferConsumer, &type);
1015
1016                if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
1017                   android_errorWriteLog(0x534e4554, "26324358");
1018                }
1019            }
1020
1021            reply->writeInt32(type);
1022            reply->writeInt32(err);
1023            return NO_ERROR;
1024        }
1025
1026        case SIGNAL_END_OF_INPUT_STREAM:
1027        {
1028            CHECK_OMX_INTERFACE(IOMX, data, reply);
1029
1030            node_id node = (node_id)data.readInt32();
1031
1032            status_t err = signalEndOfInputStream(node);
1033            reply->writeInt32(err);
1034
1035            return NO_ERROR;
1036        }
1037
1038        case STORE_META_DATA_IN_BUFFERS:
1039        {
1040            CHECK_OMX_INTERFACE(IOMX, data, reply);
1041
1042            node_id node = (node_id)data.readInt32();
1043            OMX_U32 port_index = data.readInt32();
1044            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1045
1046            MetadataBufferType type = (MetadataBufferType)data.readInt32();
1047            status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
1048
1049            reply->writeInt32(type);
1050            reply->writeInt32(err);
1051
1052            return NO_ERROR;
1053        }
1054
1055        case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1056        {
1057            CHECK_OMX_INTERFACE(IOMX, data, reply);
1058
1059            node_id node = (node_id)data.readInt32();
1060            OMX_U32 port_index = data.readInt32();
1061            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1062            OMX_U32 max_width = data.readInt32();
1063            OMX_U32 max_height = data.readInt32();
1064
1065            status_t err = prepareForAdaptivePlayback(
1066                    node, port_index, enable, max_width, max_height);
1067            reply->writeInt32(err);
1068
1069            return NO_ERROR;
1070        }
1071
1072        case CONFIGURE_VIDEO_TUNNEL_MODE:
1073        {
1074            CHECK_OMX_INTERFACE(IOMX, data, reply);
1075
1076            node_id node = (node_id)data.readInt32();
1077            OMX_U32 port_index = data.readInt32();
1078            OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1079            OMX_U32 audio_hw_sync = data.readInt32();
1080
1081            native_handle_t *sideband_handle = NULL;
1082            status_t err = configureVideoTunnelMode(
1083                    node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1084            reply->writeInt32(err);
1085            if(err == OK){
1086                reply->writeNativeHandle(sideband_handle);
1087            }
1088
1089            return NO_ERROR;
1090        }
1091
1092        case ALLOC_SECURE_BUFFER:
1093        {
1094            CHECK_OMX_INTERFACE(IOMX, data, reply);
1095
1096            node_id node = (node_id)data.readInt32();
1097            OMX_U32 port_index = data.readInt32();
1098            if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1099                ALOGE("b/24310423");
1100                reply->writeInt32(INVALID_OPERATION);
1101                return NO_ERROR;
1102            }
1103
1104            size_t size = data.readInt64();
1105
1106            buffer_id buffer;
1107            void *buffer_data = NULL;
1108            sp<NativeHandle> native_handle;
1109            status_t err = allocateSecureBuffer(
1110                    node, port_index, size, &buffer, &buffer_data, &native_handle);
1111            reply->writeInt32(err);
1112
1113            if (err == OK) {
1114                reply->writeInt32((int32_t)buffer);
1115                reply->writeInt64((uintptr_t)buffer_data);
1116                if (buffer_data == NULL) {
1117                    reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
1118                }
1119            }
1120
1121            return NO_ERROR;
1122        }
1123
1124        case ALLOC_BUFFER_WITH_BACKUP:
1125        {
1126            CHECK_OMX_INTERFACE(IOMX, data, reply);
1127
1128            node_id node = (node_id)data.readInt32();
1129            OMX_U32 port_index = data.readInt32();
1130            sp<IMemory> params =
1131                interface_cast<IMemory>(data.readStrongBinder());
1132            OMX_U32 allottedSize = data.readInt32();
1133
1134            if (params == NULL) {
1135                ALOGE("b/26392700");
1136                reply->writeInt32(INVALID_OPERATION);
1137                return NO_ERROR;
1138            }
1139
1140            buffer_id buffer;
1141            status_t err = allocateBufferWithBackup(
1142                    node, port_index, params, &buffer, allottedSize);
1143
1144            reply->writeInt32(err);
1145
1146            if (err == OK) {
1147                reply->writeInt32((int32_t)buffer);
1148            }
1149
1150            return NO_ERROR;
1151        }
1152
1153        case FREE_BUFFER:
1154        {
1155            CHECK_OMX_INTERFACE(IOMX, data, reply);
1156
1157            node_id node = (node_id)data.readInt32();
1158            OMX_U32 port_index = data.readInt32();
1159            buffer_id buffer = (buffer_id)data.readInt32();
1160            reply->writeInt32(freeBuffer(node, port_index, buffer));
1161
1162            return NO_ERROR;
1163        }
1164
1165        case FILL_BUFFER:
1166        {
1167            CHECK_OMX_INTERFACE(IOMX, data, reply);
1168
1169            node_id node = (node_id)data.readInt32();
1170            buffer_id buffer = (buffer_id)data.readInt32();
1171            bool haveFence = data.readInt32();
1172            int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1173            reply->writeInt32(fillBuffer(node, buffer, fenceFd));
1174
1175            return NO_ERROR;
1176        }
1177
1178        case EMPTY_BUFFER:
1179        {
1180            CHECK_OMX_INTERFACE(IOMX, data, reply);
1181
1182            node_id node = (node_id)data.readInt32();
1183            buffer_id buffer = (buffer_id)data.readInt32();
1184            OMX_U32 range_offset = data.readInt32();
1185            OMX_U32 range_length = data.readInt32();
1186            OMX_U32 flags = data.readInt32();
1187            OMX_TICKS timestamp = data.readInt64();
1188            bool haveFence = data.readInt32();
1189            int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1190            reply->writeInt32(emptyBuffer(
1191                    node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
1192
1193            return NO_ERROR;
1194        }
1195
1196        case GET_EXTENSION_INDEX:
1197        {
1198            CHECK_OMX_INTERFACE(IOMX, data, reply);
1199
1200            node_id node = (node_id)data.readInt32();
1201            const char *parameter_name = data.readCString();
1202
1203            if (parameter_name == NULL) {
1204                ALOGE("b/26392700");
1205                reply->writeInt32(INVALID_OPERATION);
1206                return NO_ERROR;
1207            }
1208
1209            OMX_INDEXTYPE index;
1210            status_t err = getExtensionIndex(node, parameter_name, &index);
1211
1212            reply->writeInt32(err);
1213
1214            if (err == OK) {
1215                reply->writeInt32(index);
1216            }
1217
1218            return OK;
1219        }
1220
1221        default:
1222            return BBinder::onTransact(code, data, reply, flags);
1223    }
1224}
1225
1226////////////////////////////////////////////////////////////////////////////////
1227
1228class BpOMXObserver : public BpInterface<IOMXObserver> {
1229public:
1230    BpOMXObserver(const sp<IBinder> &impl)
1231        : BpInterface<IOMXObserver>(impl) {
1232    }
1233
1234    virtual void onMessages(const std::list<omx_message> &messages) {
1235        Parcel data, reply;
1236        std::list<omx_message>::const_iterator it = messages.cbegin();
1237        bool first = true;
1238        while (it != messages.cend()) {
1239            const omx_message &msg = *it++;
1240            if (first) {
1241                data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1242                data.writeInt32(msg.node);
1243                first = false;
1244            }
1245            data.writeInt32(msg.fenceFd >= 0);
1246            if (msg.fenceFd >= 0) {
1247                data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1248            }
1249            data.writeInt32(msg.type);
1250            data.write(&msg.u, sizeof(msg.u));
1251            ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
1252        }
1253        if (!first) {
1254            data.writeInt32(-1); // mark end
1255            remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1256        }
1257    }
1258};
1259
1260IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1261
1262status_t BnOMXObserver::onTransact(
1263    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1264    switch (code) {
1265        case OBSERVER_ON_MSG:
1266        {
1267            CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
1268            IOMX::node_id node = data.readInt32();
1269            std::list<omx_message> messages;
1270            status_t err = FAILED_TRANSACTION; // must receive at least one message
1271            do {
1272                int haveFence = data.readInt32();
1273                if (haveFence < 0) { // we use -1 to mark end of messages
1274                    break;
1275                }
1276                omx_message msg;
1277                msg.node = node;
1278                msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1279                msg.type = (typeof(msg.type))data.readInt32();
1280                err = data.read(&msg.u, sizeof(msg.u));
1281                ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1282                messages.push_back(msg);
1283            } while (err == OK);
1284
1285            if (err == OK) {
1286                onMessages(messages);
1287            }
1288
1289            return err;
1290        }
1291
1292        default:
1293            return BBinder::onTransact(code, data, reply, flags);
1294    }
1295}
1296
1297}  // namespace android
1298