• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <media/OMXBuffer.h>
29 #include <utils/NativeHandle.h>
30 
31 #include <media/omx/1.0/WOmxNode.h>
32 #include <android/IGraphicBufferSource.h>
33 #include <android/IOMXBufferSource.h>
34 
35 namespace android {
36 
37 enum {
38     CONNECT = IBinder::FIRST_CALL_TRANSACTION,
39     LIST_NODES,
40     ALLOCATE_NODE,
41     CREATE_INPUT_SURFACE,
42     FREE_NODE,
43     SEND_COMMAND,
44     GET_PARAMETER,
45     SET_PARAMETER,
46     GET_CONFIG,
47     SET_CONFIG,
48     SET_PORT_MODE,
49     SET_INPUT_SURFACE,
50     PREPARE_FOR_ADAPTIVE_PLAYBACK,
51     ALLOC_SECURE_BUFFER,
52     USE_BUFFER,
53     FREE_BUFFER,
54     FILL_BUFFER,
55     EMPTY_BUFFER,
56     GET_EXTENSION_INDEX,
57     OBSERVER_ON_MSG,
58     GET_GRAPHIC_BUFFER_USAGE,
59     CONFIGURE_VIDEO_TUNNEL_MODE,
60     DISPATCH_MESSAGE,
61     SET_QUIRKS,
62 };
63 
64 class BpOMXNode : public BpInterface<IOMXNode> {
65 public:
BpOMXNode(const sp<IBinder> & impl)66     explicit BpOMXNode(const sp<IBinder> &impl)
67         : BpInterface<IOMXNode>(impl) {
68     }
69 
freeNode()70     virtual status_t freeNode() {
71         Parcel data, reply;
72         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
73         remote()->transact(FREE_NODE, data, &reply);
74 
75         return reply.readInt32();
76     }
77 
sendCommand(OMX_COMMANDTYPE cmd,OMX_S32 param)78     virtual status_t sendCommand(
79             OMX_COMMANDTYPE cmd, OMX_S32 param) {
80         Parcel data, reply;
81         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
82         data.writeInt32(cmd);
83         data.writeInt32(param);
84         remote()->transact(SEND_COMMAND, data, &reply);
85 
86         return reply.readInt32();
87     }
88 
getParameter(OMX_INDEXTYPE index,void * params,size_t size)89     virtual status_t getParameter(
90             OMX_INDEXTYPE index,
91             void *params, size_t size) {
92         Parcel data, reply;
93         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
94         data.writeInt32(index);
95         data.writeInt64(size);
96         data.write(params, size);
97         remote()->transact(GET_PARAMETER, data, &reply);
98 
99         status_t err = reply.readInt32();
100         if (err != OK) {
101             return err;
102         }
103 
104         reply.read(params, size);
105 
106         return OK;
107     }
108 
setParameter(OMX_INDEXTYPE index,const void * params,size_t size)109     virtual status_t setParameter(
110             OMX_INDEXTYPE index,
111             const void *params, size_t size) {
112         Parcel data, reply;
113         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
114         data.writeInt32(index);
115         data.writeInt64(size);
116         data.write(params, size);
117         remote()->transact(SET_PARAMETER, data, &reply);
118 
119         return reply.readInt32();
120     }
121 
getConfig(OMX_INDEXTYPE index,void * params,size_t size)122     virtual status_t getConfig(
123             OMX_INDEXTYPE index,
124             void *params, size_t size) {
125         Parcel data, reply;
126         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
127         data.writeInt32(index);
128         data.writeInt64(size);
129         data.write(params, size);
130         remote()->transact(GET_CONFIG, data, &reply);
131 
132         status_t err = reply.readInt32();
133         if (err != OK) {
134             return err;
135         }
136 
137         reply.read(params, size);
138 
139         return OK;
140     }
141 
setConfig(OMX_INDEXTYPE index,const void * params,size_t size)142     virtual status_t setConfig(
143             OMX_INDEXTYPE index,
144             const void *params, size_t size) {
145         Parcel data, reply;
146         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
147         data.writeInt32(index);
148         data.writeInt64(size);
149         data.write(params, size);
150         remote()->transact(SET_CONFIG, data, &reply);
151 
152         return reply.readInt32();
153     }
154 
setPortMode(OMX_U32 port_index,IOMX::PortMode mode)155     virtual status_t setPortMode(
156             OMX_U32 port_index, IOMX::PortMode mode) {
157         Parcel data, reply;
158         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
159         data.writeInt32(port_index);
160         data.writeInt32(mode);
161         remote()->transact(SET_PORT_MODE, data, &reply);
162 
163         return reply.readInt32();
164     }
165 
getGraphicBufferUsage(OMX_U32 port_index,OMX_U32 * usage)166     virtual status_t getGraphicBufferUsage(
167             OMX_U32 port_index, OMX_U32* usage) {
168         Parcel data, reply;
169         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
170         data.writeInt32(port_index);
171         remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
172 
173         status_t err = reply.readInt32();
174         *usage = reply.readInt32();
175         return err;
176     }
177 
useBuffer(OMX_U32 port_index,const OMXBuffer & omxBuf,buffer_id * buffer)178     virtual status_t useBuffer(
179             OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
180         Parcel data, reply;
181         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
182         data.writeInt32(port_index);
183 
184         status_t err = omxBuf.writeToParcel(&data);
185         if (err != OK) {
186             return err;
187         }
188 
189         remote()->transact(USE_BUFFER, data, &reply);
190 
191         err = reply.readInt32();
192         if (err != OK) {
193             *buffer = 0;
194 
195             return err;
196         }
197 
198         *buffer = (buffer_id)reply.readInt32();
199 
200         return err;
201     }
202 
setInputSurface(const sp<IOMXBufferSource> & bufferSource)203     virtual status_t setInputSurface(
204             const sp<IOMXBufferSource> &bufferSource) {
205         Parcel data, reply;
206         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
207 
208         data.writeStrongBinder(IInterface::asBinder(bufferSource));
209 
210         status_t err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
211 
212         if (err != OK) {
213             ALOGW("binder transaction failed: %d", err);
214             return err;
215         }
216 
217         err = reply.readInt32();
218 
219         return err;
220     }
221 
prepareForAdaptivePlayback(OMX_U32 port_index,OMX_BOOL enable,OMX_U32 max_width,OMX_U32 max_height)222     virtual status_t prepareForAdaptivePlayback(
223             OMX_U32 port_index, OMX_BOOL enable,
224             OMX_U32 max_width, OMX_U32 max_height) {
225         Parcel data, reply;
226         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
227         data.writeInt32(port_index);
228         data.writeInt32((int32_t)enable);
229         data.writeInt32(max_width);
230         data.writeInt32(max_height);
231         remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
232 
233         status_t err = reply.readInt32();
234         return err;
235     }
236 
configureVideoTunnelMode(OMX_U32 portIndex,OMX_BOOL tunneled,OMX_U32 audioHwSync,native_handle_t ** sidebandHandle)237     virtual status_t configureVideoTunnelMode(
238             OMX_U32 portIndex, OMX_BOOL tunneled,
239             OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
240         Parcel data, reply;
241         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
242         data.writeInt32(portIndex);
243         data.writeInt32((int32_t)tunneled);
244         data.writeInt32(audioHwSync);
245         remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
246 
247         status_t err = reply.readInt32();
248         if (err == OK && sidebandHandle) {
249             *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
250         }
251         return err;
252     }
253 
254 
allocateSecureBuffer(OMX_U32 port_index,size_t size,buffer_id * buffer,void ** buffer_data,sp<NativeHandle> * native_handle)255     virtual status_t allocateSecureBuffer(
256             OMX_U32 port_index, size_t size,
257             buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
258         Parcel data, reply;
259         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
260         data.writeInt32(port_index);
261         data.writeInt64(size);
262         remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
263 
264         status_t err = reply.readInt32();
265         if (err != OK) {
266             *buffer = 0;
267             *buffer_data = NULL;
268             *native_handle = NULL;
269             return err;
270         }
271 
272         *buffer = (buffer_id)reply.readInt32();
273         *buffer_data = (void *)reply.readInt64();
274         if (*buffer_data == NULL) {
275             *native_handle = NativeHandle::create(
276                     reply.readNativeHandle(), true /* ownsHandle */);
277         } else {
278             *native_handle = NULL;
279         }
280         return err;
281     }
282 
freeBuffer(OMX_U32 port_index,buffer_id buffer)283     virtual status_t freeBuffer(
284             OMX_U32 port_index, buffer_id buffer) {
285         Parcel data, reply;
286         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
287         data.writeInt32(port_index);
288         data.writeInt32((int32_t)buffer);
289         remote()->transact(FREE_BUFFER, data, &reply);
290 
291         return reply.readInt32();
292     }
293 
fillBuffer(buffer_id buffer,const OMXBuffer & omxBuf,int fenceFd)294     virtual status_t fillBuffer(
295             buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
296         Parcel data, reply;
297         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
298         data.writeInt32((int32_t)buffer);
299         status_t err = omxBuf.writeToParcel(&data);
300         if (err != OK) {
301             return err;
302         }
303         data.writeInt32(fenceFd >= 0);
304         if (fenceFd >= 0) {
305             data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
306         }
307         remote()->transact(FILL_BUFFER, data, &reply);
308 
309         return reply.readInt32();
310     }
311 
emptyBuffer(buffer_id buffer,const OMXBuffer & omxBuf,OMX_U32 flags,OMX_TICKS timestamp,int fenceFd)312     virtual status_t emptyBuffer(
313             buffer_id buffer, const OMXBuffer &omxBuf,
314             OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
315         Parcel data, reply;
316         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
317         data.writeInt32((int32_t)buffer);
318         status_t err = omxBuf.writeToParcel(&data);
319         if (err != OK) {
320             return err;
321         }
322         data.writeInt32(flags);
323         data.writeInt64(timestamp);
324         data.writeInt32(fenceFd >= 0);
325         if (fenceFd >= 0) {
326             data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
327         }
328         remote()->transact(EMPTY_BUFFER, data, &reply);
329 
330         return reply.readInt32();
331     }
332 
getExtensionIndex(const char * parameter_name,OMX_INDEXTYPE * index)333     virtual status_t getExtensionIndex(
334             const char *parameter_name,
335             OMX_INDEXTYPE *index) {
336         Parcel data, reply;
337         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
338         data.writeCString(parameter_name);
339 
340         remote()->transact(GET_EXTENSION_INDEX, data, &reply);
341 
342         status_t err = reply.readInt32();
343         if (err == OK) {
344             *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
345         } else {
346             *index = OMX_IndexComponentStartUnused;
347         }
348 
349         return err;
350     }
351 
dispatchMessage(const omx_message & msg)352     virtual status_t dispatchMessage(const omx_message &msg) {
353         Parcel data, reply;
354         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
355         data.writeInt32(msg.fenceFd >= 0);
356         if (msg.fenceFd >= 0) {
357             data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
358         }
359         data.writeInt32(msg.type);
360         data.write(&msg.u, sizeof(msg.u));
361 
362         remote()->transact(DISPATCH_MESSAGE, data, &reply);
363 
364         return reply.readInt32();
365     }
366 
setQuirks(OMX_U32 quirks)367     virtual status_t setQuirks(OMX_U32 quirks) {
368         Parcel data, reply;
369         data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
370         data.writeInt32(quirks);
371 
372         remote()->transact(SET_QUIRKS, data, &reply);
373 
374         return reply.readInt32();
375     }
376 };
377 
378 using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
379 class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> {
380 public:
HpOMXNode(const sp<IBinder> & base)381     HpOMXNode(const sp<IBinder>& base) : PBase(base) {}
382 
freeNode()383     virtual status_t freeNode() {
384         return mBase->freeNode();
385     }
386 
sendCommand(OMX_COMMANDTYPE cmd,OMX_S32 param)387     virtual status_t sendCommand(
388             OMX_COMMANDTYPE cmd, OMX_S32 param) {
389         return mBase->sendCommand(cmd, param);
390     }
391 
getParameter(OMX_INDEXTYPE index,void * params,size_t size)392     virtual status_t getParameter(
393             OMX_INDEXTYPE index, void *params, size_t size) {
394         return mBase->getParameter(index, params, size);
395     }
396 
setParameter(OMX_INDEXTYPE index,const void * params,size_t size)397     virtual status_t setParameter(
398             OMX_INDEXTYPE index, const void *params, size_t size) {
399         return mBase->setParameter(index, params, size);
400     }
401 
getConfig(OMX_INDEXTYPE index,void * params,size_t size)402     virtual status_t getConfig(
403             OMX_INDEXTYPE index, void *params, size_t size) {
404         return mBase->getConfig(index, params, size);
405     }
406 
setConfig(OMX_INDEXTYPE index,const void * params,size_t size)407     virtual status_t setConfig(
408             OMX_INDEXTYPE index, const void *params, size_t size) {
409         return mBase->setConfig(index, params, size);
410     }
411 
setPortMode(OMX_U32 port_index,IOMX::PortMode mode)412     virtual status_t setPortMode(
413             OMX_U32 port_index, IOMX::PortMode mode) {
414         return mBase->setPortMode(port_index, mode);
415     }
416 
prepareForAdaptivePlayback(OMX_U32 portIndex,OMX_BOOL enable,OMX_U32 maxFrameWidth,OMX_U32 maxFrameHeight)417     virtual status_t prepareForAdaptivePlayback(
418             OMX_U32 portIndex, OMX_BOOL enable,
419             OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
420         return mBase->prepareForAdaptivePlayback(
421                 portIndex, enable, maxFrameWidth, maxFrameHeight);
422     }
423 
configureVideoTunnelMode(OMX_U32 portIndex,OMX_BOOL tunneled,OMX_U32 audioHwSync,native_handle_t ** sidebandHandle)424     virtual status_t configureVideoTunnelMode(
425             OMX_U32 portIndex, OMX_BOOL tunneled,
426             OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
427         return mBase->configureVideoTunnelMode(
428                 portIndex, tunneled, audioHwSync, sidebandHandle);
429     }
430 
getGraphicBufferUsage(OMX_U32 port_index,OMX_U32 * usage)431     virtual status_t getGraphicBufferUsage(
432             OMX_U32 port_index, OMX_U32* usage) {
433         return mBase->getGraphicBufferUsage(port_index, usage);
434     }
435 
setInputSurface(const sp<IOMXBufferSource> & bufferSource)436     virtual status_t setInputSurface(
437             const sp<IOMXBufferSource> &bufferSource) {
438         return mBase->setInputSurface(bufferSource);
439     }
440 
allocateSecureBuffer(OMX_U32 port_index,size_t size,buffer_id * buffer,void ** buffer_data,sp<NativeHandle> * native_handle)441     virtual status_t allocateSecureBuffer(
442             OMX_U32 port_index, size_t size, buffer_id *buffer,
443             void **buffer_data, sp<NativeHandle> *native_handle) {
444         return mBase->allocateSecureBuffer(
445                 port_index, size, buffer, buffer_data, native_handle);
446     }
447 
useBuffer(OMX_U32 port_index,const OMXBuffer & omxBuf,buffer_id * buffer)448     virtual status_t useBuffer(
449             OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
450         return mBase->useBuffer(port_index, omxBuf, buffer);
451     }
452 
freeBuffer(OMX_U32 port_index,buffer_id buffer)453     virtual status_t freeBuffer(
454             OMX_U32 port_index, buffer_id buffer) {
455         return mBase->freeBuffer(port_index, buffer);
456     }
457 
fillBuffer(buffer_id buffer,const OMXBuffer & omxBuf,int fenceFd=-1)458     virtual status_t fillBuffer(
459             buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) {
460         return mBase->fillBuffer(buffer, omxBuf, fenceFd);
461     }
462 
emptyBuffer(buffer_id buffer,const OMXBuffer & omxBuf,OMX_U32 flags,OMX_TICKS timestamp,int fenceFd=-1)463     virtual status_t emptyBuffer(
464             buffer_id buffer, const OMXBuffer &omxBuf,
465             OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) {
466         return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
467     }
468 
getExtensionIndex(const char * parameter_name,OMX_INDEXTYPE * index)469     virtual status_t getExtensionIndex(
470             const char *parameter_name,
471             OMX_INDEXTYPE *index) {
472         return mBase->getExtensionIndex(parameter_name, index);
473     }
474 
dispatchMessage(const omx_message & msg)475     virtual status_t dispatchMessage(const omx_message &msg) {
476         return mBase->dispatchMessage(msg);
477     }
478 };
479 
480 IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 
484 #define CHECK_OMX_INTERFACE(interface, data, reply) \
485         do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
486             ALOGW("Call incorrectly routed to " #interface); \
487             return PERMISSION_DENIED; \
488         } } while (0)
489 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)490 status_t BnOMXNode::onTransact(
491     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
492     switch (code) {
493         case FREE_NODE:
494         {
495             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
496 
497             reply->writeInt32(freeNode());
498 
499             return NO_ERROR;
500         }
501 
502         case SEND_COMMAND:
503         {
504             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
505 
506             OMX_COMMANDTYPE cmd =
507                 static_cast<OMX_COMMANDTYPE>(data.readInt32());
508 
509             OMX_S32 param = data.readInt32();
510             reply->writeInt32(sendCommand(cmd, param));
511 
512             return NO_ERROR;
513         }
514 
515         case GET_PARAMETER:
516         case SET_PARAMETER:
517         case GET_CONFIG:
518         case SET_CONFIG:
519         {
520             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
521 
522             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
523 
524             size_t size = data.readInt64();
525 
526             status_t err = NOT_ENOUGH_DATA;
527             void *params = NULL;
528             size_t pageSize = 0;
529             size_t allocSize = 0;
530             bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
531             if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) {
532                 // we expect the structure to contain at least the size and
533                 // version, 8 bytes total
534                 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
535                 android_errorWriteLog(0x534e4554, "27207275");
536             } else {
537                 err = NO_MEMORY;
538                 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
539                 if (size > SIZE_MAX - (pageSize * 2)) {
540                     ALOGE("requested param size too big");
541                 } else {
542                     allocSize = (size + pageSize * 2) & ~(pageSize - 1);
543                     params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
544                             MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
545                 }
546                 if (params != MAP_FAILED && params != NULL) {
547                     err = data.read(params, size);
548                     if (err != OK) {
549                         android_errorWriteLog(0x534e4554, "26914474");
550                     } else {
551                         err = NOT_ENOUGH_DATA;
552                         OMX_U32 declaredSize = *(OMX_U32*)params;
553                         if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
554                                 declaredSize > size) {
555                             // the buffer says it's bigger than it actually is
556                             ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
557                             android_errorWriteLog(0x534e4554, "27207275");
558                         } else {
559                             // mark the last page as inaccessible, to avoid exploitation
560                             // of codecs that access past the end of the allocation because
561                             // they didn't check the size
562                             if (mprotect((char*)params + allocSize - pageSize, pageSize,
563                                     PROT_NONE) != 0) {
564                                 ALOGE("mprotect failed: %s", strerror(errno));
565                             } else {
566                                 switch (code) {
567                                     case GET_PARAMETER:
568                                         err = getParameter(index, params, size);
569                                         break;
570                                     case SET_PARAMETER:
571                                         err = setParameter(index, params, size);
572                                         break;
573                                     case GET_CONFIG:
574                                         err = getConfig(index, params, size);
575                                         break;
576                                     case SET_CONFIG:
577                                         err = setConfig(index, params, size);
578                                         break;
579                                     default:
580                                         TRESPASS();
581                                 }
582                             }
583                         }
584                     }
585                 } else {
586                     ALOGE("couldn't map: %s", strerror(errno));
587                 }
588             }
589 
590             reply->writeInt32(err);
591 
592             if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
593                 reply->write(params, size);
594             }
595 
596             if (params) {
597                 munmap(params, allocSize);
598             }
599             params = NULL;
600 
601             return NO_ERROR;
602         }
603 
604         case SET_PORT_MODE:
605         {
606             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
607             OMX_U32 port_index = data.readInt32();
608             IOMX::PortMode mode = (IOMX::PortMode) data.readInt32();
609             reply->writeInt32(setPortMode(port_index, mode));
610 
611             return NO_ERROR;
612         }
613 
614         case GET_GRAPHIC_BUFFER_USAGE:
615         {
616             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
617 
618             OMX_U32 port_index = data.readInt32();
619 
620             OMX_U32 usage = 0;
621             status_t err = getGraphicBufferUsage(port_index, &usage);
622             reply->writeInt32(err);
623             reply->writeInt32(usage);
624 
625             return NO_ERROR;
626         }
627 
628         case USE_BUFFER:
629         {
630             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
631 
632             OMX_U32 port_index = data.readInt32();
633 
634             OMXBuffer omxBuf;
635             status_t err = omxBuf.readFromParcel(&data);
636             if (err != OK) {
637                 return err;
638             }
639 
640             buffer_id buffer;
641             err = useBuffer(port_index, omxBuf, &buffer);
642             reply->writeInt32(err);
643 
644             if (err == OK) {
645                 reply->writeInt32((int32_t)buffer);
646             }
647 
648             return NO_ERROR;
649         }
650 
651         case SET_INPUT_SURFACE:
652         {
653             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
654 
655             sp<IOMXBufferSource> bufferSource =
656                     interface_cast<IOMXBufferSource>(data.readStrongBinder());
657 
658             status_t err = setInputSurface(bufferSource);
659             reply->writeInt32(err);
660 
661             return NO_ERROR;
662         }
663 
664         case PREPARE_FOR_ADAPTIVE_PLAYBACK:
665         {
666             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
667 
668             OMX_U32 port_index = data.readInt32();
669             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
670             OMX_U32 max_width = data.readInt32();
671             OMX_U32 max_height = data.readInt32();
672 
673             status_t err = prepareForAdaptivePlayback(
674                     port_index, enable, max_width, max_height);
675             reply->writeInt32(err);
676 
677             return NO_ERROR;
678         }
679 
680         case CONFIGURE_VIDEO_TUNNEL_MODE:
681         {
682             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
683 
684             OMX_U32 port_index = data.readInt32();
685             OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
686             OMX_U32 audio_hw_sync = data.readInt32();
687 
688             native_handle_t *sideband_handle = NULL;
689             status_t err = configureVideoTunnelMode(
690                     port_index, tunneled, audio_hw_sync, &sideband_handle);
691             reply->writeInt32(err);
692             if(err == OK){
693                 reply->writeNativeHandle(sideband_handle);
694             }
695 
696             return NO_ERROR;
697         }
698 
699         case ALLOC_SECURE_BUFFER:
700         {
701             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
702 
703             OMX_U32 port_index = data.readInt32();
704             if (!isSecure() || port_index != 0 /* kPortIndexInput */) {
705                 ALOGE("b/24310423");
706                 reply->writeInt32(INVALID_OPERATION);
707                 return NO_ERROR;
708             }
709 
710             size_t size = data.readInt64();
711 
712             buffer_id buffer;
713             void *buffer_data = NULL;
714             sp<NativeHandle> native_handle;
715             status_t err = allocateSecureBuffer(
716                     port_index, size, &buffer, &buffer_data, &native_handle);
717             reply->writeInt32(err);
718 
719             if (err == OK) {
720                 reply->writeInt32((int32_t)buffer);
721                 reply->writeInt64((uintptr_t)buffer_data);
722                 if (buffer_data == NULL) {
723                     reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
724                 }
725             }
726 
727             return NO_ERROR;
728         }
729 
730         case FREE_BUFFER:
731         {
732             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
733 
734             OMX_U32 port_index = data.readInt32();
735             buffer_id buffer = (buffer_id)data.readInt32();
736             reply->writeInt32(freeBuffer(port_index, buffer));
737 
738             return NO_ERROR;
739         }
740 
741         case FILL_BUFFER:
742         {
743             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
744 
745             buffer_id buffer = (buffer_id)data.readInt32();
746 
747             OMXBuffer omxBuf;
748             status_t err = omxBuf.readFromParcel(&data);
749             if (err != OK) {
750                 return err;
751             }
752 
753             bool haveFence = data.readInt32();
754             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
755 
756             reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd));
757 
758             return NO_ERROR;
759         }
760 
761         case EMPTY_BUFFER:
762         {
763             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
764 
765             buffer_id buffer = (buffer_id)data.readInt32();
766             OMXBuffer omxBuf;
767             status_t err = omxBuf.readFromParcel(&data);
768             if (err != OK) {
769                 return err;
770             }
771             OMX_U32 flags = data.readInt32();
772             OMX_TICKS timestamp = data.readInt64();
773             bool haveFence = data.readInt32();
774             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
775             reply->writeInt32(emptyBuffer(
776                     buffer, omxBuf, flags, timestamp, fenceFd));
777 
778             return NO_ERROR;
779         }
780 
781         case GET_EXTENSION_INDEX:
782         {
783             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
784 
785             const char *parameter_name = data.readCString();
786 
787             if (parameter_name == NULL) {
788                 ALOGE("b/26392700");
789                 reply->writeInt32(INVALID_OPERATION);
790                 return NO_ERROR;
791             }
792 
793             OMX_INDEXTYPE index;
794             status_t err = getExtensionIndex(parameter_name, &index);
795 
796             reply->writeInt32(err);
797 
798             if (err == OK) {
799                 reply->writeInt32(index);
800             }
801 
802             return OK;
803         }
804 
805         case DISPATCH_MESSAGE:
806         {
807             CHECK_OMX_INTERFACE(IOMXNode, data, reply);
808             omx_message msg;
809             int haveFence = data.readInt32();
810             msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
811             msg.type = (typeof(msg.type))data.readInt32();
812             status_t err = data.read(&msg.u, sizeof(msg.u));
813 
814             if (err == OK) {
815                 err = dispatchMessage(msg);
816             }
817             reply->writeInt32(err);
818 
819             return NO_ERROR;
820         }
821 
822         default:
823             return BBinder::onTransact(code, data, reply, flags);
824     }
825 }
826 
827 ////////////////////////////////////////////////////////////////////////////////
828 
829 class BpOMXObserver : public BpInterface<IOMXObserver> {
830 public:
BpOMXObserver(const sp<IBinder> & impl)831     explicit BpOMXObserver(const sp<IBinder> &impl)
832         : BpInterface<IOMXObserver>(impl) {
833     }
834 
onMessages(const std::list<omx_message> & messages)835     virtual void onMessages(const std::list<omx_message> &messages) {
836         Parcel data, reply;
837         std::list<omx_message>::const_iterator it = messages.cbegin();
838         if (messages.empty()) {
839             return;
840         }
841         data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
842         while (it != messages.cend()) {
843             const omx_message &msg = *it++;
844             data.writeInt32(msg.fenceFd >= 0);
845             if (msg.fenceFd >= 0) {
846                 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
847             }
848             data.writeInt32(msg.type);
849             data.write(&msg.u, sizeof(msg.u));
850             ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
851         }
852         data.writeInt32(-1); // mark end
853         remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
854     }
855 };
856 
857 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
858 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)859 status_t BnOMXObserver::onTransact(
860     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
861     switch (code) {
862         case OBSERVER_ON_MSG:
863         {
864             CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
865             std::list<omx_message> messages;
866             status_t err = FAILED_TRANSACTION; // must receive at least one message
867             do {
868                 int haveFence = data.readInt32();
869                 if (haveFence < 0) { // we use -1 to mark end of messages
870                     break;
871                 }
872                 omx_message msg;
873                 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
874                 msg.type = (typeof(msg.type))data.readInt32();
875                 err = data.read(&msg.u, sizeof(msg.u));
876                 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
877                 messages.push_back(msg);
878             } while (err == OK);
879 
880             if (err == OK) {
881                 onMessages(messages);
882             }
883 
884             return err;
885         }
886 
887         default:
888             return BBinder::onTransact(code, data, reply, flags);
889     }
890 }
891 
892 }  // namespace android
893