blob: 5063504ba39e97ce6090f983053ec0013b18f956 [file] [log] [blame]
James Dong27c17442011-03-17 11:02:04 -07001/*
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
Andreas Huber20111aa2009-07-14 16:56:47 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "IOMX"
19#include <utils/Log.h>
20
Marco Nelissen2720c8b2016-02-29 12:47:20 -080021#include <sys/mman.h>
22
Andreas Huber20111aa2009-07-14 16:56:47 -070023#include <binder/IMemory.h>
24#include <binder/Parcel.h>
25#include <media/IOMX.h>
Andreas Huberb3912902011-01-19 10:34:52 -080026#include <media/stagefright/foundation/ADebug.h>
Marco Nelissenc1c50e72016-03-10 15:02:13 -080027#include <media/openmax/OMX_IndexExt.h>
Lajos Molnar7e0bef82016-05-09 10:48:30 -070028#include <utils/NativeHandle.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070029
Chong Zhang6d332d22016-09-07 12:06:50 -070030#include <android/IGraphicBufferSource.h>
31
Andreas Huber20111aa2009-07-14 16:56:47 -070032namespace android {
33
34enum {
35 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
36 LIST_NODES,
37 ALLOCATE_NODE,
38 FREE_NODE,
39 SEND_COMMAND,
40 GET_PARAMETER,
41 SET_PARAMETER,
Andreas Huber693d2712009-08-14 14:37:10 -070042 GET_CONFIG,
43 SET_CONFIG,
Jamie Gennisb1d666f2011-10-19 21:14:13 -070044 GET_STATE,
Lajos Molnara63141a2016-02-11 16:40:36 -080045 ENABLE_NATIVE_BUFFERS,
Andreas Huber20111aa2009-07-14 16:56:47 -070046 USE_BUFFER,
Jamie Gennis83750ea2010-08-30 16:48:38 -070047 USE_GRAPHIC_BUFFER,
Andy McFadden7cd58532013-02-19 07:28:30 -080048 CREATE_INPUT_SURFACE,
Chong Zhangd291c222015-04-30 18:15:52 -070049 CREATE_PERSISTENT_INPUT_SURFACE,
Chong Zhang8f469e12015-05-13 10:21:33 -070050 SET_INPUT_SURFACE,
James Donge8707722010-10-20 17:38:41 -070051 STORE_META_DATA_IN_BUFFERS,
Lajos Molnar56ce7262013-05-02 16:30:48 -070052 PREPARE_FOR_ADAPTIVE_PLAYBACK,
Lajos Molnara63141a2016-02-11 16:40:36 -080053 ALLOC_SECURE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070054 ALLOC_BUFFER_WITH_BACKUP,
55 FREE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070056 FILL_BUFFER,
57 EMPTY_BUFFER,
Chong Zhang6cf9a122016-09-08 23:25:52 -070058 EMPTY_GRAPHIC_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070059 GET_EXTENSION_INDEX,
Andreas Huber20111aa2009-07-14 16:56:47 -070060 OBSERVER_ON_MSG,
Jamie Gennise2ce6452011-02-23 19:01:28 -080061 GET_GRAPHIC_BUFFER_USAGE,
Lajos Molnard0715862013-07-22 12:57:43 -070062 UPDATE_GRAPHIC_BUFFER_IN_META,
Rachad5a446aa2014-07-29 16:47:56 -070063 CONFIGURE_VIDEO_TUNNEL_MODE,
Lajos Molnar7e0bef82016-05-09 10:48:30 -070064 UPDATE_NATIVE_HANDLE_IN_META,
Chong Zhang6cf9a122016-09-08 23:25:52 -070065 DISPATCH_MESSAGE,
Andreas Huber20111aa2009-07-14 16:56:47 -070066};
67
Andreas Huber20111aa2009-07-14 16:56:47 -070068class BpOMX : public BpInterface<IOMX> {
69public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070070 explicit BpOMX(const sp<IBinder> &impl)
Andreas Huber20111aa2009-07-14 16:56:47 -070071 : BpInterface<IOMX>(impl) {
72 }
73
Chong Zhangd59b9722016-09-20 16:31:18 -070074 virtual bool livesLocally() {
75 return false;
Andreas Huber7eaa9c92010-01-15 15:28:19 -080076 }
77
Andreas Huber134ee6a2009-12-16 09:30:55 -080078 virtual status_t listNodes(List<ComponentInfo> *list) {
Andreas Huber20111aa2009-07-14 16:56:47 -070079 list->clear();
80
81 Parcel data, reply;
82 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
83 remote()->transact(LIST_NODES, data, &reply);
84
85 int32_t n = reply.readInt32();
86 for (int32_t i = 0; i < n; ++i) {
Andreas Huber134ee6a2009-12-16 09:30:55 -080087 list->push_back(ComponentInfo());
88 ComponentInfo &info = *--list->end();
Andreas Huber20111aa2009-07-14 16:56:47 -070089
Andreas Huber134ee6a2009-12-16 09:30:55 -080090 info.mName = reply.readString8();
91 int32_t numRoles = reply.readInt32();
92 for (int32_t j = 0; j < numRoles; ++j) {
93 info.mRoles.push_back(reply.readString8());
94 }
Andreas Huber20111aa2009-07-14 16:56:47 -070095 }
96
97 return OK;
98 }
99
Andreas Huber318ad9c2009-10-15 13:46:54 -0700100 virtual status_t allocateNode(
Marco Nelissen23858872016-02-17 13:12:13 -0800101 const char *name, const sp<IOMXObserver> &observer,
Chong Zhang1d2e9cf2016-10-05 21:08:36 -0700102 sp<IOMXNode> *omxNode) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700103 Parcel data, reply;
104 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
105 data.writeCString(name);
Marco Nelissen06b46062014-11-14 07:58:25 -0800106 data.writeStrongBinder(IInterface::asBinder(observer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700107 remote()->transact(ALLOCATE_NODE, data, &reply);
108
109 status_t err = reply.readInt32();
110 if (err == OK) {
Chong Zhangd59b9722016-09-20 16:31:18 -0700111 *omxNode = IOMXNode::asInterface(reply.readStrongBinder());
Andreas Huber20111aa2009-07-14 16:56:47 -0700112 } else {
Chong Zhangd59b9722016-09-20 16:31:18 -0700113 omxNode->clear();
Andreas Huber20111aa2009-07-14 16:56:47 -0700114 }
115
116 return err;
117 }
118
Chong Zhangd291c222015-04-30 18:15:52 -0700119 virtual status_t createPersistentInputSurface(
120 sp<IGraphicBufferProducer> *bufferProducer,
121 sp<IGraphicBufferConsumer> *bufferConsumer) {
122 Parcel data, reply;
123 status_t err;
124 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
125 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
126 if (err != OK) {
127 ALOGW("binder transaction failed: %d", err);
128 return err;
129 }
130
131 err = reply.readInt32();
132 if (err != OK) {
133 return err;
134 }
135
136 *bufferProducer = IGraphicBufferProducer::asInterface(
137 reply.readStrongBinder());
138 *bufferConsumer = IGraphicBufferConsumer::asInterface(
139 reply.readStrongBinder());
140
141 return err;
142 }
Chong Zhangd59b9722016-09-20 16:31:18 -0700143};
144
145class BpOMXNode : public BpInterface<IOMXNode> {
146public:
147 explicit BpOMXNode(const sp<IBinder> &impl)
148 : BpInterface<IOMXNode>(impl) {
149 }
150
151 virtual status_t freeNode() {
152 Parcel data, reply;
153 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
154 remote()->transact(FREE_NODE, data, &reply);
155
156 return reply.readInt32();
157 }
158
159 virtual status_t sendCommand(
160 OMX_COMMANDTYPE cmd, OMX_S32 param) {
161 Parcel data, reply;
162 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
163 data.writeInt32(cmd);
164 data.writeInt32(param);
165 remote()->transact(SEND_COMMAND, data, &reply);
166
167 return reply.readInt32();
168 }
169
170 virtual status_t getParameter(
171 OMX_INDEXTYPE index,
172 void *params, size_t size) {
173 Parcel data, reply;
174 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
175 data.writeInt32(index);
176 data.writeInt64(size);
177 data.write(params, size);
178 remote()->transact(GET_PARAMETER, data, &reply);
179
180 status_t err = reply.readInt32();
181 if (err != OK) {
182 return err;
183 }
184
185 reply.read(params, size);
186
187 return OK;
188 }
189
190 virtual status_t setParameter(
191 OMX_INDEXTYPE index,
192 const void *params, size_t size) {
193 Parcel data, reply;
194 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
195 data.writeInt32(index);
196 data.writeInt64(size);
197 data.write(params, size);
198 remote()->transact(SET_PARAMETER, data, &reply);
199
200 return reply.readInt32();
201 }
202
203 virtual status_t getConfig(
204 OMX_INDEXTYPE index,
205 void *params, size_t size) {
206 Parcel data, reply;
207 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
208 data.writeInt32(index);
209 data.writeInt64(size);
210 data.write(params, size);
211 remote()->transact(GET_CONFIG, data, &reply);
212
213 status_t err = reply.readInt32();
214 if (err != OK) {
215 return err;
216 }
217
218 reply.read(params, size);
219
220 return OK;
221 }
222
223 virtual status_t setConfig(
224 OMX_INDEXTYPE index,
225 const void *params, size_t size) {
226 Parcel data, reply;
227 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
228 data.writeInt32(index);
229 data.writeInt64(size);
230 data.write(params, size);
231 remote()->transact(SET_CONFIG, data, &reply);
232
233 return reply.readInt32();
234 }
235
236 virtual status_t getState(
237 OMX_STATETYPE* state) {
238 Parcel data, reply;
239 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
240 remote()->transact(GET_STATE, data, &reply);
241
242 *state = static_cast<OMX_STATETYPE>(reply.readInt32());
243 return reply.readInt32();
244 }
245
246 virtual status_t enableNativeBuffers(
247 OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
248 Parcel data, reply;
249 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
250 data.writeInt32(port_index);
251 data.writeInt32((uint32_t)graphic);
252 data.writeInt32((uint32_t)enable);
253 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
254
255 status_t err = reply.readInt32();
256 return err;
257 }
258
259 virtual status_t getGraphicBufferUsage(
260 OMX_U32 port_index, OMX_U32* usage) {
261 Parcel data, reply;
262 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
263 data.writeInt32(port_index);
264 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
265
266 status_t err = reply.readInt32();
267 *usage = reply.readInt32();
268 return err;
269 }
270
271 virtual status_t useBuffer(
272 OMX_U32 port_index, const sp<IMemory> &params,
273 buffer_id *buffer, OMX_U32 allottedSize) {
274 Parcel data, reply;
275 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
276 data.writeInt32(port_index);
277 data.writeStrongBinder(IInterface::asBinder(params));
278 data.writeInt32(allottedSize);
279 remote()->transact(USE_BUFFER, data, &reply);
280
281 status_t err = reply.readInt32();
282 if (err != OK) {
283 *buffer = 0;
284
285 return err;
286 }
287
288 *buffer = (buffer_id)reply.readInt32();
289
290 return err;
291 }
292
293
294 virtual status_t useGraphicBuffer(
295 OMX_U32 port_index,
296 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
297 Parcel data, reply;
298 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
299 data.writeInt32(port_index);
300 data.write(*graphicBuffer);
301 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
302
303 status_t err = reply.readInt32();
304 if (err != OK) {
305 *buffer = 0;
306
307 return err;
308 }
309
310 *buffer = (buffer_id)reply.readInt32();
311
312 return err;
313 }
314
315 virtual status_t updateGraphicBufferInMeta(
316 OMX_U32 port_index,
317 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
318 Parcel data, reply;
319 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
320 data.writeInt32(port_index);
321 data.write(*graphicBuffer);
322 data.writeInt32((int32_t)buffer);
323 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
324
325 status_t err = reply.readInt32();
326 return err;
327 }
328
329 virtual status_t updateNativeHandleInMeta(
330 OMX_U32 port_index,
331 const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
332 Parcel data, reply;
333 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
334 data.writeInt32(port_index);
335 data.writeInt32(nativeHandle != NULL);
336 if (nativeHandle != NULL) {
337 data.writeNativeHandle(nativeHandle->handle());
338 }
339 data.writeInt32((int32_t)buffer);
340 remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply);
341
342 status_t err = reply.readInt32();
343 return err;
344 }
345
346 virtual status_t createInputSurface(
347 OMX_U32 port_index, android_dataspace dataSpace,
348 sp<IGraphicBufferProducer> *bufferProducer,
349 sp<IGraphicBufferSource> *bufferSource,
350 MetadataBufferType *type) {
351 Parcel data, reply;
352 status_t err;
353 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
354 data.writeInt32(port_index);
355 data.writeInt32(dataSpace);
356 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
357 if (err != OK) {
358 ALOGW("binder transaction failed: %d", err);
359 return err;
360 }
361
362 // read type even if createInputSurface failed
363 int negotiatedType = reply.readInt32();
364 if (type != NULL) {
365 *type = (MetadataBufferType)negotiatedType;
366 }
367
368 err = reply.readInt32();
369 if (err != OK) {
370 return err;
371 }
372
373 *bufferProducer = IGraphicBufferProducer::asInterface(
374 reply.readStrongBinder());
375 *bufferSource = IGraphicBufferSource::asInterface(
376 reply.readStrongBinder());
377
378 return err;
379 }
Chong Zhangd291c222015-04-30 18:15:52 -0700380
Chong Zhang8f469e12015-05-13 10:21:33 -0700381 virtual status_t setInputSurface(
Chong Zhangd59b9722016-09-20 16:31:18 -0700382 OMX_U32 port_index,
Chong Zhang6d332d22016-09-07 12:06:50 -0700383 const sp<IGraphicBufferConsumer> &bufferConsumer,
384 sp<IGraphicBufferSource> *bufferSource,
385 MetadataBufferType *type) {
Chong Zhangd291c222015-04-30 18:15:52 -0700386 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700387 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Chong Zhangd291c222015-04-30 18:15:52 -0700388 status_t err;
Chong Zhangd291c222015-04-30 18:15:52 -0700389 data.writeInt32(port_index);
390 data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
391
Chong Zhang8f469e12015-05-13 10:21:33 -0700392 err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700393
394 if (err != OK) {
395 ALOGW("binder transaction failed: %d", err);
396 return err;
397 }
Lajos Molnar05421982015-05-15 20:39:14 -0700398
399 // read type even if setInputSurface failed
400 int negotiatedType = reply.readInt32();
401 if (type != NULL) {
402 *type = (MetadataBufferType)negotiatedType;
403 }
404
Chong Zhang6d332d22016-09-07 12:06:50 -0700405 err = reply.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800406 if (err != OK) {
Andy McFadden7cd58532013-02-19 07:28:30 -0800407 return err;
408 }
409
Chong Zhang6d332d22016-09-07 12:06:50 -0700410 *bufferSource = IGraphicBufferSource::asInterface(
411 reply.readStrongBinder());
412
413 return err;
Andy McFadden7cd58532013-02-19 07:28:30 -0800414 }
415
James Donge8707722010-10-20 17:38:41 -0700416 virtual status_t storeMetaDataInBuffers(
Chong Zhangd59b9722016-09-20 16:31:18 -0700417 OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
James Donge8707722010-10-20 17:38:41 -0700418 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700419 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
James Donge8707722010-10-20 17:38:41 -0700420 data.writeInt32(port_index);
Lajos Molnar3e328782016-05-09 10:56:46 -0700421 data.writeInt32((int32_t)enable);
422 data.writeInt32(type == NULL ? kMetadataBufferTypeANWBuffer : *type);
423
James Donge8707722010-10-20 17:38:41 -0700424 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
425
Lajos Molnar05421982015-05-15 20:39:14 -0700426 // read type even storeMetaDataInBuffers failed
427 int negotiatedType = reply.readInt32();
428 if (type != NULL) {
429 *type = (MetadataBufferType)negotiatedType;
430 }
431
432 return reply.readInt32();
James Donge8707722010-10-20 17:38:41 -0700433 }
434
Lajos Molnar56ce7262013-05-02 16:30:48 -0700435 virtual status_t prepareForAdaptivePlayback(
Chong Zhangd59b9722016-09-20 16:31:18 -0700436 OMX_U32 port_index, OMX_BOOL enable,
Lajos Molnar56ce7262013-05-02 16:30:48 -0700437 OMX_U32 max_width, OMX_U32 max_height) {
438 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700439 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Lajos Molnar56ce7262013-05-02 16:30:48 -0700440 data.writeInt32(port_index);
441 data.writeInt32((int32_t)enable);
442 data.writeInt32(max_width);
443 data.writeInt32(max_height);
444 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
445
446 status_t err = reply.readInt32();
447 return err;
448 }
449
Rachad5a446aa2014-07-29 16:47:56 -0700450 virtual status_t configureVideoTunnelMode(
Chong Zhangd59b9722016-09-20 16:31:18 -0700451 OMX_U32 portIndex, OMX_BOOL tunneled,
Rachad5a446aa2014-07-29 16:47:56 -0700452 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
453 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700454 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Rachad5a446aa2014-07-29 16:47:56 -0700455 data.writeInt32(portIndex);
456 data.writeInt32((int32_t)tunneled);
457 data.writeInt32(audioHwSync);
458 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
459
460 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800461 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700462 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
463 }
464 return err;
465 }
466
467
Lajos Molnara63141a2016-02-11 16:40:36 -0800468 virtual status_t allocateSecureBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700469 OMX_U32 port_index, size_t size,
Lajos Molnar1b40f282016-05-09 22:24:52 -0700470 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700471 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700472 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber20111aa2009-07-14 16:56:47 -0700473 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800474 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800475 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700476
477 status_t err = reply.readInt32();
478 if (err != OK) {
479 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800480 *buffer_data = NULL;
481 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700482 return err;
483 }
484
Andy Hung609b8152014-05-02 11:05:04 -0700485 *buffer = (buffer_id)reply.readInt32();
486 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800487 if (*buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -0700488 *native_handle = NativeHandle::create(
489 reply.readNativeHandle(), true /* ownsHandle */);
Lajos Molnara63141a2016-02-11 16:40:36 -0800490 } else {
491 *native_handle = NULL;
492 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700493 return err;
494 }
495
Andreas Huber318ad9c2009-10-15 13:46:54 -0700496 virtual status_t allocateBufferWithBackup(
Chong Zhangd59b9722016-09-20 16:31:18 -0700497 OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700498 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700499 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700500 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber20111aa2009-07-14 16:56:47 -0700501 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800502 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700503 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700504 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
505
506 status_t err = reply.readInt32();
507 if (err != OK) {
508 *buffer = 0;
509
510 return err;
511 }
512
Andy Hung609b8152014-05-02 11:05:04 -0700513 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700514
515 return err;
516 }
517
Andreas Huber318ad9c2009-10-15 13:46:54 -0700518 virtual status_t freeBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700519 OMX_U32 port_index, buffer_id buffer) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700520 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700521 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber20111aa2009-07-14 16:56:47 -0700522 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700523 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700524 remote()->transact(FREE_BUFFER, data, &reply);
525
526 return reply.readInt32();
527 }
528
Chong Zhangd59b9722016-09-20 16:31:18 -0700529 virtual status_t fillBuffer(buffer_id buffer, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700530 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700531 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700532 data.writeInt32((int32_t)buffer);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700533 data.writeInt32(fenceFd >= 0);
534 if (fenceFd >= 0) {
535 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
536 }
Andreas Huber36efa032009-10-08 11:02:27 -0700537 remote()->transact(FILL_BUFFER, data, &reply);
538
539 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700540 }
541
Andreas Huber318ad9c2009-10-15 13:46:54 -0700542 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700543 buffer_id buffer,
544 OMX_U32 range_offset, OMX_U32 range_length,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700545 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700546 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700547 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700548 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700549 data.writeInt32(range_offset);
550 data.writeInt32(range_length);
551 data.writeInt32(flags);
552 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700553 data.writeInt32(fenceFd >= 0);
554 if (fenceFd >= 0) {
555 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
556 }
Andreas Huber36efa032009-10-08 11:02:27 -0700557 remote()->transact(EMPTY_BUFFER, data, &reply);
558
559 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700560 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700561
Chong Zhang6cf9a122016-09-08 23:25:52 -0700562 virtual status_t emptyGraphicBuffer(
Chong Zhang6cf9a122016-09-08 23:25:52 -0700563 buffer_id buffer,
Chong Zhang6d332d22016-09-07 12:06:50 -0700564 const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
565 OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd) {
Chong Zhang6cf9a122016-09-08 23:25:52 -0700566 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700567 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Chong Zhang6cf9a122016-09-08 23:25:52 -0700568 data.writeInt32((int32_t)buffer);
569 data.write(*graphicBuffer);
570 data.writeInt32(flags);
571 data.writeInt64(timestamp);
Chong Zhang6d332d22016-09-07 12:06:50 -0700572 data.writeInt64(origTimestamp);
Chong Zhang6cf9a122016-09-08 23:25:52 -0700573 data.writeInt32(fenceFd >= 0);
574 if (fenceFd >= 0) {
575 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
576 }
577 remote()->transact(EMPTY_GRAPHIC_BUFFER, data, &reply);
578
579 return reply.readInt32();
580 }
581
Andreas Huber318ad9c2009-10-15 13:46:54 -0700582 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700583 const char *parameter_name,
584 OMX_INDEXTYPE *index) {
585 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700586 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber693d2712009-08-14 14:37:10 -0700587 data.writeCString(parameter_name);
588
589 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
590
591 status_t err = reply.readInt32();
592 if (err == OK) {
593 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
594 } else {
595 *index = OMX_IndexComponentStartUnused;
596 }
597
598 return err;
599 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700600
Chong Zhang6cf9a122016-09-08 23:25:52 -0700601 virtual status_t dispatchMessage(const omx_message &msg) {
602 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700603 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Chong Zhang6cf9a122016-09-08 23:25:52 -0700604 data.writeInt32(msg.fenceFd >= 0);
605 if (msg.fenceFd >= 0) {
606 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
607 }
608 data.writeInt32(msg.type);
609 data.write(&msg.u, sizeof(msg.u));
610
611 remote()->transact(DISPATCH_MESSAGE, data, &reply);
612
613 return reply.readInt32();
614 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700615};
616
617IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
Chong Zhangd59b9722016-09-20 16:31:18 -0700618IMPLEMENT_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
Andreas Huber20111aa2009-07-14 16:56:47 -0700619
620////////////////////////////////////////////////////////////////////////////////
621
Andy McFadden7cd58532013-02-19 07:28:30 -0800622#define CHECK_OMX_INTERFACE(interface, data, reply) \
Chih-Hung Hsieh83fbbb82016-05-17 15:08:10 -0700623 do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000624 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700625 return PERMISSION_DENIED; \
626 } } while (0)
627
628status_t BnOMX::onTransact(
629 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
630 switch (code) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700631 case LIST_NODES:
632 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800633 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700634
Andreas Huber134ee6a2009-12-16 09:30:55 -0800635 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700636 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700637
638 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800639 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700640 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800641 ComponentInfo &cur = *it;
642
643 reply->writeString8(cur.mName);
644 reply->writeInt32(cur.mRoles.size());
645 for (List<String8>::iterator role_it = cur.mRoles.begin();
646 role_it != cur.mRoles.end(); ++role_it) {
647 reply->writeString8(*role_it);
648 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700649 }
650
651 return NO_ERROR;
652 }
653
654 case ALLOCATE_NODE:
655 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800656 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700657
Andreas Huber318ad9c2009-10-15 13:46:54 -0700658 const char *name = data.readCString();
659
660 sp<IOMXObserver> observer =
661 interface_cast<IOMXObserver>(data.readStrongBinder());
662
Wei Jia56c95c92016-01-06 10:30:46 -0800663 if (name == NULL || observer == NULL) {
664 ALOGE("b/26392700");
665 reply->writeInt32(INVALID_OPERATION);
666 return NO_ERROR;
667 }
668
Chong Zhangd59b9722016-09-20 16:31:18 -0700669 sp<IOMXNode> omxNode;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700670
Chong Zhang1d2e9cf2016-10-05 21:08:36 -0700671 status_t err = allocateNode(name, observer, &omxNode);
Chong Zhangd59b9722016-09-20 16:31:18 -0700672
Andreas Huber20111aa2009-07-14 16:56:47 -0700673 reply->writeInt32(err);
674 if (err == OK) {
Chong Zhangd59b9722016-09-20 16:31:18 -0700675 reply->writeStrongBinder(IInterface::asBinder(omxNode));
Andreas Huber20111aa2009-07-14 16:56:47 -0700676 }
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800677
Andreas Huber20111aa2009-07-14 16:56:47 -0700678 return NO_ERROR;
679 }
680
Chong Zhangd59b9722016-09-20 16:31:18 -0700681 case CREATE_PERSISTENT_INPUT_SURFACE:
Andreas Huber20111aa2009-07-14 16:56:47 -0700682 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800683 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700684
Chong Zhangd59b9722016-09-20 16:31:18 -0700685 sp<IGraphicBufferProducer> bufferProducer;
686 sp<IGraphicBufferConsumer> bufferConsumer;
687 status_t err = createPersistentInputSurface(
688 &bufferProducer, &bufferConsumer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700689
Chong Zhangd59b9722016-09-20 16:31:18 -0700690 reply->writeInt32(err);
691
692 if (err == OK) {
693 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
694 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
695 }
696
697 return NO_ERROR;
698 }
699
700 default:
701 return BBinder::onTransact(code, data, reply, flags);
702 }
703}
704
705status_t BnOMXNode::onTransact(
706 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
707 switch (code) {
708 case FREE_NODE:
709 {
710 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
711
712 reply->writeInt32(freeNode());
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800713
Andreas Huber20111aa2009-07-14 16:56:47 -0700714 return NO_ERROR;
715 }
716
717 case SEND_COMMAND:
718 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700719 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700720
721 OMX_COMMANDTYPE cmd =
722 static_cast<OMX_COMMANDTYPE>(data.readInt32());
723
724 OMX_S32 param = data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700725 reply->writeInt32(sendCommand(cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700726
727 return NO_ERROR;
728 }
729
730 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700731 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700732 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700733 case SET_CONFIG:
734 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700735 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700736
Andreas Huber693d2712009-08-14 14:37:10 -0700737 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
738
Glenn Kastene03dd222014-01-28 11:04:39 -0800739 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700740
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800741 status_t err = NOT_ENOUGH_DATA;
742 void *params = NULL;
743 size_t pageSize = 0;
744 size_t allocSize = 0;
Marco Nelissen788b0b62016-03-21 11:31:53 -0700745 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
Chong Zhang6d332d22016-09-07 12:06:50 -0700746 if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800747 // we expect the structure to contain at least the size and
748 // version, 8 bytes total
Marco Nelissen788b0b62016-03-21 11:31:53 -0700749 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800750 android_errorWriteLog(0x534e4554, "27207275");
751 } else {
752 err = NO_MEMORY;
753 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
754 if (size > SIZE_MAX - (pageSize * 2)) {
755 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800756 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800757 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
758 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
759 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
760 }
761 if (params != MAP_FAILED) {
762 err = data.read(params, size);
763 if (err != OK) {
764 android_errorWriteLog(0x534e4554, "26914474");
765 } else {
766 err = NOT_ENOUGH_DATA;
767 OMX_U32 declaredSize = *(OMX_U32*)params;
Chong Zhang6d332d22016-09-07 12:06:50 -0700768 if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
Marco Nelissenc1c50e72016-03-10 15:02:13 -0800769 declaredSize > size) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800770 // the buffer says it's bigger than it actually is
771 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
772 android_errorWriteLog(0x534e4554, "27207275");
773 } else {
774 // mark the last page as inaccessible, to avoid exploitation
775 // of codecs that access past the end of the allocation because
776 // they didn't check the size
Marco Nelissen866c8002016-09-20 13:36:40 -0700777 if (mprotect((char*)params + allocSize - pageSize, pageSize,
778 PROT_NONE) != 0) {
779 ALOGE("mprotect failed: %s", strerror(errno));
780 } else {
781 switch (code) {
782 case GET_PARAMETER:
Chong Zhangd59b9722016-09-20 16:31:18 -0700783 err = getParameter(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700784 break;
785 case SET_PARAMETER:
Chong Zhangd59b9722016-09-20 16:31:18 -0700786 err = setParameter(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700787 break;
788 case GET_CONFIG:
Chong Zhangd59b9722016-09-20 16:31:18 -0700789 err = getConfig(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700790 break;
791 case SET_CONFIG:
Chong Zhangd59b9722016-09-20 16:31:18 -0700792 err = setConfig(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700793 break;
Marco Nelissen866c8002016-09-20 13:36:40 -0700794 default:
795 TRESPASS();
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800796 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800797 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800798 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800799 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800800 } else {
801 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700802 }
Andreas Huberb3912902011-01-19 10:34:52 -0800803 }
804
805 reply->writeInt32(err);
806
807 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
808 reply->write(params, size);
809 }
810
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800811 if (params) {
812 munmap(params, allocSize);
813 }
Andreas Huberb3912902011-01-19 10:34:52 -0800814 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700815
816 return NO_ERROR;
817 }
818
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700819 case GET_STATE:
820 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700821 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700822
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700823 OMX_STATETYPE state = OMX_StateInvalid;
824
Chong Zhangd59b9722016-09-20 16:31:18 -0700825 status_t err = getState(&state);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700826 reply->writeInt32(state);
827 reply->writeInt32(err);
828
829 return NO_ERROR;
830 }
831
Lajos Molnara63141a2016-02-11 16:40:36 -0800832 case ENABLE_NATIVE_BUFFERS:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700833 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700834 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700835
Jamie Gennis83750ea2010-08-30 16:48:38 -0700836 OMX_U32 port_index = data.readInt32();
Lajos Molnara63141a2016-02-11 16:40:36 -0800837 OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700838 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
839
Chong Zhangd59b9722016-09-20 16:31:18 -0700840 status_t err = enableNativeBuffers(port_index, graphic, enable);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700841 reply->writeInt32(err);
842
843 return NO_ERROR;
844 }
845
Jamie Gennise2ce6452011-02-23 19:01:28 -0800846 case GET_GRAPHIC_BUFFER_USAGE:
847 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700848 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800849
Jamie Gennise2ce6452011-02-23 19:01:28 -0800850 OMX_U32 port_index = data.readInt32();
851
852 OMX_U32 usage = 0;
Chong Zhangd59b9722016-09-20 16:31:18 -0700853 status_t err = getGraphicBufferUsage(port_index, &usage);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800854 reply->writeInt32(err);
855 reply->writeInt32(usage);
856
857 return NO_ERROR;
858 }
859
Andreas Huber20111aa2009-07-14 16:56:47 -0700860 case USE_BUFFER:
861 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700862 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700863
Andreas Huber20111aa2009-07-14 16:56:47 -0700864 OMX_U32 port_index = data.readInt32();
865 sp<IMemory> params =
866 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700867 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700868
Wei Jia56c95c92016-01-06 10:30:46 -0800869 if (params == NULL) {
870 ALOGE("b/26392700");
871 reply->writeInt32(INVALID_OPERATION);
872 return NO_ERROR;
873 }
874
Andreas Huber20111aa2009-07-14 16:56:47 -0700875 buffer_id buffer;
Chong Zhangd59b9722016-09-20 16:31:18 -0700876 status_t err = useBuffer(port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700877 reply->writeInt32(err);
878
879 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700880 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700881 }
882
883 return NO_ERROR;
884 }
885
Jamie Gennis83750ea2010-08-30 16:48:38 -0700886 case USE_GRAPHIC_BUFFER:
887 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700888 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700889
Jamie Gennis83750ea2010-08-30 16:48:38 -0700890 OMX_U32 port_index = data.readInt32();
891 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
892 data.read(*graphicBuffer);
893
894 buffer_id buffer;
895 status_t err = useGraphicBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700896 port_index, graphicBuffer, &buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700897 reply->writeInt32(err);
898
899 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700900 reply->writeInt32((int32_t)buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700901 }
902
903 return NO_ERROR;
904 }
905
Lajos Molnard0715862013-07-22 12:57:43 -0700906 case UPDATE_GRAPHIC_BUFFER_IN_META:
907 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700908 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Lajos Molnard0715862013-07-22 12:57:43 -0700909
Lajos Molnard0715862013-07-22 12:57:43 -0700910 OMX_U32 port_index = data.readInt32();
911 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
912 data.read(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700913 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700914
915 status_t err = updateGraphicBufferInMeta(
Chong Zhangd59b9722016-09-20 16:31:18 -0700916 port_index, graphicBuffer, buffer);
Lajos Molnard0715862013-07-22 12:57:43 -0700917 reply->writeInt32(err);
918
919 return NO_ERROR;
920 }
921
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700922 case UPDATE_NATIVE_HANDLE_IN_META:
923 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700924 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700925
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700926 OMX_U32 port_index = data.readInt32();
927 native_handle *handle = NULL;
928 if (data.readInt32()) {
929 handle = data.readNativeHandle();
930 }
931 buffer_id buffer = (buffer_id)data.readInt32();
932
933 status_t err = updateNativeHandleInMeta(
Chong Zhangd59b9722016-09-20 16:31:18 -0700934 port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700935 reply->writeInt32(err);
936
937 return NO_ERROR;
938 }
939
Andy McFadden7cd58532013-02-19 07:28:30 -0800940 case CREATE_INPUT_SURFACE:
941 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700942 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andy McFadden7cd58532013-02-19 07:28:30 -0800943
Andy McFadden7cd58532013-02-19 07:28:30 -0800944 OMX_U32 port_index = data.readInt32();
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800945 android_dataspace dataSpace = (android_dataspace)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800946
947 sp<IGraphicBufferProducer> bufferProducer;
Chong Zhang6d332d22016-09-07 12:06:50 -0700948 sp<IGraphicBufferSource> bufferSource;
mspector@google.comda9ca912016-02-08 17:07:06 -0800949 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhang6d332d22016-09-07 12:06:50 -0700950 status_t err = createInputSurface(
Chong Zhangd59b9722016-09-20 16:31:18 -0700951 port_index, dataSpace, &bufferProducer, &bufferSource, &type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800952
mspector@google.comda9ca912016-02-08 17:07:06 -0800953 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
954 android_errorWriteLog(0x534e4554, "26324358");
955 }
956
Lajos Molnar05421982015-05-15 20:39:14 -0700957 reply->writeInt32(type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800958 reply->writeInt32(err);
959
960 if (err == OK) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800961 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
Chong Zhang6d332d22016-09-07 12:06:50 -0700962 reply->writeStrongBinder(IInterface::asBinder(bufferSource));
Andy McFadden7cd58532013-02-19 07:28:30 -0800963 }
964
965 return NO_ERROR;
966 }
967
Chong Zhang8f469e12015-05-13 10:21:33 -0700968 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700969 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700970 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700971
Chong Zhangd291c222015-04-30 18:15:52 -0700972 OMX_U32 port_index = data.readInt32();
973
974 sp<IGraphicBufferConsumer> bufferConsumer =
975 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
976
Chong Zhang6d332d22016-09-07 12:06:50 -0700977 sp<IGraphicBufferSource> bufferSource;
Wei Jia56c95c92016-01-06 10:30:46 -0800978 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhangd291c222015-04-30 18:15:52 -0700979
Wei Jia56c95c92016-01-06 10:30:46 -0800980 status_t err = INVALID_OPERATION;
981 if (bufferConsumer == NULL) {
982 ALOGE("b/26392700");
983 } else {
Chong Zhangd59b9722016-09-20 16:31:18 -0700984 err = setInputSurface(port_index, bufferConsumer, &bufferSource, &type);
mspector@google.comc3ed9d02016-02-18 19:52:08 -0800985
986 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
987 android_errorWriteLog(0x534e4554, "26324358");
988 }
Wei Jia56c95c92016-01-06 10:30:46 -0800989 }
Chong Zhangd291c222015-04-30 18:15:52 -0700990
Lajos Molnar05421982015-05-15 20:39:14 -0700991 reply->writeInt32(type);
Chong Zhangd291c222015-04-30 18:15:52 -0700992 reply->writeInt32(err);
Chong Zhang6d332d22016-09-07 12:06:50 -0700993 if (err == OK) {
994 reply->writeStrongBinder(IInterface::asBinder(bufferSource));
995 }
Andy McFadden7cd58532013-02-19 07:28:30 -0800996 return NO_ERROR;
997 }
998
James Donge8707722010-10-20 17:38:41 -0700999 case STORE_META_DATA_IN_BUFFERS:
1000 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001001 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
James Donge8707722010-10-20 17:38:41 -07001002
James Donge8707722010-10-20 17:38:41 -07001003 OMX_U32 port_index = data.readInt32();
1004 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1005
Lajos Molnar3e328782016-05-09 10:56:46 -07001006 MetadataBufferType type = (MetadataBufferType)data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -07001007 status_t err = storeMetaDataInBuffers(port_index, enable, &type);
mspector@google.comda9ca912016-02-08 17:07:06 -08001008
Lajos Molnar05421982015-05-15 20:39:14 -07001009 reply->writeInt32(type);
James Donge8707722010-10-20 17:38:41 -07001010 reply->writeInt32(err);
1011
1012 return NO_ERROR;
1013 }
1014
Lajos Molnar56ce7262013-05-02 16:30:48 -07001015 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1016 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001017 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Lajos Molnar56ce7262013-05-02 16:30:48 -07001018
Lajos Molnar56ce7262013-05-02 16:30:48 -07001019 OMX_U32 port_index = data.readInt32();
1020 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1021 OMX_U32 max_width = data.readInt32();
1022 OMX_U32 max_height = data.readInt32();
1023
1024 status_t err = prepareForAdaptivePlayback(
Chong Zhangd59b9722016-09-20 16:31:18 -07001025 port_index, enable, max_width, max_height);
Lajos Molnar56ce7262013-05-02 16:30:48 -07001026 reply->writeInt32(err);
1027
1028 return NO_ERROR;
1029 }
1030
Rachad5a446aa2014-07-29 16:47:56 -07001031 case CONFIGURE_VIDEO_TUNNEL_MODE:
1032 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001033 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Rachad5a446aa2014-07-29 16:47:56 -07001034
Rachad5a446aa2014-07-29 16:47:56 -07001035 OMX_U32 port_index = data.readInt32();
1036 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1037 OMX_U32 audio_hw_sync = data.readInt32();
1038
Lajos Molnara63141a2016-02-11 16:40:36 -08001039 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -07001040 status_t err = configureVideoTunnelMode(
Chong Zhangd59b9722016-09-20 16:31:18 -07001041 port_index, tunneled, audio_hw_sync, &sideband_handle);
Rachad5a446aa2014-07-29 16:47:56 -07001042 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -08001043 if(err == OK){
1044 reply->writeNativeHandle(sideband_handle);
1045 }
Rachad5a446aa2014-07-29 16:47:56 -07001046
1047 return NO_ERROR;
1048 }
1049
Lajos Molnara63141a2016-02-11 16:40:36 -08001050 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -07001051 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001052 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001053
Andreas Huber20111aa2009-07-14 16:56:47 -07001054 OMX_U32 port_index = data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -07001055 if (!isSecure() || port_index != 0 /* kPortIndexInput */) {
Wei Jia8dde7262015-09-28 11:32:23 -07001056 ALOGE("b/24310423");
1057 reply->writeInt32(INVALID_OPERATION);
1058 return NO_ERROR;
1059 }
1060
Glenn Kastene03dd222014-01-28 11:04:39 -08001061 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -07001062
1063 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -08001064 void *buffer_data = NULL;
Lajos Molnar1b40f282016-05-09 22:24:52 -07001065 sp<NativeHandle> native_handle;
Lajos Molnara63141a2016-02-11 16:40:36 -08001066 status_t err = allocateSecureBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -07001067 port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -07001068 reply->writeInt32(err);
1069
1070 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001071 reply->writeInt32((int32_t)buffer);
1072 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -08001073 if (buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -07001074 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
Lajos Molnara63141a2016-02-11 16:40:36 -08001075 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001076 }
1077
1078 return NO_ERROR;
1079 }
1080
1081 case ALLOC_BUFFER_WITH_BACKUP:
1082 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001083 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001084
Andreas Huber20111aa2009-07-14 16:56:47 -07001085 OMX_U32 port_index = data.readInt32();
1086 sp<IMemory> params =
1087 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001088 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001089
Wei Jia56c95c92016-01-06 10:30:46 -08001090 if (params == NULL) {
1091 ALOGE("b/26392700");
1092 reply->writeInt32(INVALID_OPERATION);
1093 return NO_ERROR;
1094 }
1095
Andreas Huber20111aa2009-07-14 16:56:47 -07001096 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001097 status_t err = allocateBufferWithBackup(
Chong Zhangd59b9722016-09-20 16:31:18 -07001098 port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -07001099
1100 reply->writeInt32(err);
1101
1102 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001103 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -07001104 }
1105
1106 return NO_ERROR;
1107 }
1108
1109 case FREE_BUFFER:
1110 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001111 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001112
Andreas Huber20111aa2009-07-14 16:56:47 -07001113 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -07001114 buffer_id buffer = (buffer_id)data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -07001115 reply->writeInt32(freeBuffer(port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -07001116
1117 return NO_ERROR;
1118 }
1119
1120 case FILL_BUFFER:
1121 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001122 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001123
Andy Hung609b8152014-05-02 11:05:04 -07001124 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001125 bool haveFence = data.readInt32();
1126 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
Chong Zhangd59b9722016-09-20 16:31:18 -07001127 reply->writeInt32(fillBuffer(buffer, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001128
1129 return NO_ERROR;
1130 }
1131
1132 case EMPTY_BUFFER:
1133 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001134 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001135
Andy Hung609b8152014-05-02 11:05:04 -07001136 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001137 OMX_U32 range_offset = data.readInt32();
1138 OMX_U32 range_length = data.readInt32();
1139 OMX_U32 flags = data.readInt32();
1140 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001141 bool haveFence = data.readInt32();
1142 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1143 reply->writeInt32(emptyBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -07001144 buffer, range_offset, range_length, flags, timestamp, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001145
1146 return NO_ERROR;
1147 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001148
Chong Zhang6cf9a122016-09-08 23:25:52 -07001149 case EMPTY_GRAPHIC_BUFFER:
1150 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001151 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Chong Zhang6cf9a122016-09-08 23:25:52 -07001152
Chong Zhang6cf9a122016-09-08 23:25:52 -07001153 buffer_id buffer = (buffer_id)data.readInt32();
1154 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
1155 data.read(*graphicBuffer);
1156 OMX_U32 flags = data.readInt32();
1157 OMX_TICKS timestamp = data.readInt64();
Chong Zhang6d332d22016-09-07 12:06:50 -07001158 OMX_TICKS origTimestamp = data.readInt64();
Chong Zhang6cf9a122016-09-08 23:25:52 -07001159 bool haveFence = data.readInt32();
1160 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1161 reply->writeInt32(emptyGraphicBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -07001162 buffer, graphicBuffer, flags,
Chong Zhang6d332d22016-09-07 12:06:50 -07001163 timestamp, origTimestamp, fenceFd));
Chong Zhang6cf9a122016-09-08 23:25:52 -07001164
1165 return NO_ERROR;
1166 }
1167
Andreas Huber693d2712009-08-14 14:37:10 -07001168 case GET_EXTENSION_INDEX:
1169 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001170 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -07001171
Andreas Huber693d2712009-08-14 14:37:10 -07001172 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -08001173
Wei Jia56c95c92016-01-06 10:30:46 -08001174 if (parameter_name == NULL) {
1175 ALOGE("b/26392700");
1176 reply->writeInt32(INVALID_OPERATION);
1177 return NO_ERROR;
1178 }
1179
Andreas Huber693d2712009-08-14 14:37:10 -07001180 OMX_INDEXTYPE index;
Chong Zhangd59b9722016-09-20 16:31:18 -07001181 status_t err = getExtensionIndex(parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -07001182
1183 reply->writeInt32(err);
1184
1185 if (err == OK) {
1186 reply->writeInt32(index);
1187 }
1188
1189 return OK;
1190 }
1191
Chong Zhang6cf9a122016-09-08 23:25:52 -07001192 case DISPATCH_MESSAGE:
1193 {
Chong Zhangd59b9722016-09-20 16:31:18 -07001194 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Chong Zhang6cf9a122016-09-08 23:25:52 -07001195 omx_message msg;
Chong Zhang6cf9a122016-09-08 23:25:52 -07001196 int haveFence = data.readInt32();
1197 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1198 msg.type = (typeof(msg.type))data.readInt32();
1199 status_t err = data.read(&msg.u, sizeof(msg.u));
1200
1201 if (err == OK) {
1202 err = dispatchMessage(msg);
1203 }
1204 reply->writeInt32(err);
1205
1206 return NO_ERROR;
1207 }
1208
Andreas Huber20111aa2009-07-14 16:56:47 -07001209 default:
1210 return BBinder::onTransact(code, data, reply, flags);
1211 }
1212}
1213
1214////////////////////////////////////////////////////////////////////////////////
1215
1216class BpOMXObserver : public BpInterface<IOMXObserver> {
1217public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -07001218 explicit BpOMXObserver(const sp<IBinder> &impl)
Andreas Huber20111aa2009-07-14 16:56:47 -07001219 : BpInterface<IOMXObserver>(impl) {
1220 }
1221
Lajos Molnar26a48f32015-06-04 10:30:02 -07001222 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -07001223 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001224 std::list<omx_message>::const_iterator it = messages.cbegin();
Chong Zhangd59b9722016-09-20 16:31:18 -07001225 if (messages.empty()) {
1226 return;
1227 }
1228 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
Lajos Molnar26a48f32015-06-04 10:30:02 -07001229 while (it != messages.cend()) {
1230 const omx_message &msg = *it++;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001231 data.writeInt32(msg.fenceFd >= 0);
1232 if (msg.fenceFd >= 0) {
1233 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1234 }
1235 data.writeInt32(msg.type);
1236 data.write(&msg.u, sizeof(msg.u));
1237 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -07001238 }
Chong Zhangd59b9722016-09-20 16:31:18 -07001239 data.writeInt32(-1); // mark end
1240 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
Andreas Huber20111aa2009-07-14 16:56:47 -07001241 }
1242};
1243
1244IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1245
1246status_t BnOMXObserver::onTransact(
1247 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1248 switch (code) {
1249 case OBSERVER_ON_MSG:
1250 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001251 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -07001252 std::list<omx_message> messages;
1253 status_t err = FAILED_TRANSACTION; // must receive at least one message
1254 do {
1255 int haveFence = data.readInt32();
1256 if (haveFence < 0) { // we use -1 to mark end of messages
1257 break;
1258 }
1259 omx_message msg;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001260 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1261 msg.type = (typeof(msg.type))data.readInt32();
1262 err = data.read(&msg.u, sizeof(msg.u));
1263 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1264 messages.push_back(msg);
1265 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -07001266
Lajos Molnar26a48f32015-06-04 10:30:02 -07001267 if (err == OK) {
1268 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -07001269 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001270
Lajos Molnar26a48f32015-06-04 10:30:02 -07001271 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -07001272 }
1273
1274 default:
1275 return BBinder::onTransact(code, data, reply, flags);
1276 }
1277}
1278
Andreas Huber20111aa2009-07-14 16:56:47 -07001279} // namespace android