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