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