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