blob: 959a3d7622449d7a0a3c87e7c1b52dda36701e64 [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>
Chong Zhang3fd200f2016-10-07 17:25:58 -070028#include <media/OMXBuffer.h>
Mathias Agopianbc1713d2017-02-13 18:37:50 -080029#include <utils/NativeHandle.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070030
Pawin Vongmasad2075e82017-07-11 04:50:40 -070031#include <media/omx/1.0/WOmxNode.h>
Chong Zhangaddf2cb2016-09-28 17:53:01 -070032#include <android/IOMXBufferSource.h>
Chong Zhang6d332d22016-09-07 12:06:50 -070033
Andreas Huber20111aa2009-07-14 16:56:47 -070034namespace android {
35
36enum {
37 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
38 LIST_NODES,
39 ALLOCATE_NODE,
Chong Zhangd02c0862016-10-13 14:32:32 -070040 CREATE_INPUT_SURFACE,
Andreas Huber20111aa2009-07-14 16:56:47 -070041 FREE_NODE,
42 SEND_COMMAND,
43 GET_PARAMETER,
44 SET_PARAMETER,
Andreas Huber693d2712009-08-14 14:37:10 -070045 GET_CONFIG,
46 SET_CONFIG,
Chong Zhangd02c0862016-10-13 14:32:32 -070047 SET_PORT_MODE,
Chong Zhang8f469e12015-05-13 10:21:33 -070048 SET_INPUT_SURFACE,
Lajos Molnar56ce7262013-05-02 16:30:48 -070049 PREPARE_FOR_ADAPTIVE_PLAYBACK,
Lajos Molnara63141a2016-02-11 16:40:36 -080050 ALLOC_SECURE_BUFFER,
Chong Zhangd02c0862016-10-13 14:32:32 -070051 USE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070052 FREE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070053 FILL_BUFFER,
54 EMPTY_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070055 GET_EXTENSION_INDEX,
Andreas Huber20111aa2009-07-14 16:56:47 -070056 OBSERVER_ON_MSG,
Jamie Gennise2ce6452011-02-23 19:01:28 -080057 GET_GRAPHIC_BUFFER_USAGE,
Rachad5a446aa2014-07-29 16:47:56 -070058 CONFIGURE_VIDEO_TUNNEL_MODE,
Chong Zhang6cf9a122016-09-08 23:25:52 -070059 DISPATCH_MESSAGE,
Chong Zhang21b46582016-10-04 12:44:53 -070060 SET_QUIRKS,
Andreas Huber20111aa2009-07-14 16:56:47 -070061};
62
Chong Zhangd59b9722016-09-20 16:31:18 -070063class BpOMXNode : public BpInterface<IOMXNode> {
64public:
65 explicit BpOMXNode(const sp<IBinder> &impl)
66 : BpInterface<IOMXNode>(impl) {
67 }
68
69 virtual status_t freeNode() {
70 Parcel data, reply;
71 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
72 remote()->transact(FREE_NODE, data, &reply);
73
74 return reply.readInt32();
75 }
76
77 virtual status_t sendCommand(
78 OMX_COMMANDTYPE cmd, OMX_S32 param) {
79 Parcel data, reply;
80 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
81 data.writeInt32(cmd);
82 data.writeInt32(param);
83 remote()->transact(SEND_COMMAND, data, &reply);
84
85 return reply.readInt32();
86 }
87
88 virtual status_t getParameter(
89 OMX_INDEXTYPE index,
90 void *params, size_t size) {
91 Parcel data, reply;
92 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
93 data.writeInt32(index);
94 data.writeInt64(size);
95 data.write(params, size);
96 remote()->transact(GET_PARAMETER, data, &reply);
97
98 status_t err = reply.readInt32();
99 if (err != OK) {
100 return err;
101 }
102
103 reply.read(params, size);
104
105 return OK;
106 }
107
108 virtual status_t setParameter(
109 OMX_INDEXTYPE index,
110 const void *params, size_t size) {
111 Parcel data, reply;
112 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
113 data.writeInt32(index);
114 data.writeInt64(size);
115 data.write(params, size);
116 remote()->transact(SET_PARAMETER, data, &reply);
117
118 return reply.readInt32();
119 }
120
121 virtual status_t getConfig(
122 OMX_INDEXTYPE index,
123 void *params, size_t size) {
124 Parcel data, reply;
125 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
126 data.writeInt32(index);
127 data.writeInt64(size);
128 data.write(params, size);
129 remote()->transact(GET_CONFIG, data, &reply);
130
131 status_t err = reply.readInt32();
132 if (err != OK) {
133 return err;
134 }
135
136 reply.read(params, size);
137
138 return OK;
139 }
140
141 virtual status_t setConfig(
142 OMX_INDEXTYPE index,
143 const void *params, size_t size) {
144 Parcel data, reply;
145 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
146 data.writeInt32(index);
147 data.writeInt64(size);
148 data.write(params, size);
149 remote()->transact(SET_CONFIG, data, &reply);
150
151 return reply.readInt32();
152 }
153
Chong Zhangd02c0862016-10-13 14:32:32 -0700154 virtual status_t setPortMode(
155 OMX_U32 port_index, IOMX::PortMode mode) {
Chong Zhangd59b9722016-09-20 16:31:18 -0700156 Parcel data, reply;
157 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
158 data.writeInt32(port_index);
Chong Zhangd02c0862016-10-13 14:32:32 -0700159 data.writeInt32(mode);
160 remote()->transact(SET_PORT_MODE, data, &reply);
Chong Zhangd59b9722016-09-20 16:31:18 -0700161
Chong Zhangd02c0862016-10-13 14:32:32 -0700162 return reply.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700163 }
164
165 virtual status_t getGraphicBufferUsage(
166 OMX_U32 port_index, OMX_U32* usage) {
167 Parcel data, reply;
168 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
169 data.writeInt32(port_index);
170 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
171
172 status_t err = reply.readInt32();
173 *usage = reply.readInt32();
174 return err;
175 }
176
177 virtual status_t useBuffer(
Chong Zhang3fd200f2016-10-07 17:25:58 -0700178 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
Chong Zhangd59b9722016-09-20 16:31:18 -0700179 Parcel data, reply;
180 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
181 data.writeInt32(port_index);
Chong Zhang3fd200f2016-10-07 17:25:58 -0700182
183 status_t err = omxBuf.writeToParcel(&data);
184 if (err != OK) {
185 return err;
186 }
187
Chong Zhangd59b9722016-09-20 16:31:18 -0700188 remote()->transact(USE_BUFFER, data, &reply);
189
Chong Zhang3fd200f2016-10-07 17:25:58 -0700190 err = reply.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700191 if (err != OK) {
192 *buffer = 0;
193
194 return err;
195 }
196
197 *buffer = (buffer_id)reply.readInt32();
198
199 return err;
200 }
201
Chong Zhang8f469e12015-05-13 10:21:33 -0700202 virtual status_t setInputSurface(
Chong Zhangaddf2cb2016-09-28 17:53:01 -0700203 const sp<IOMXBufferSource> &bufferSource) {
Chong Zhangd291c222015-04-30 18:15:52 -0700204 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700205 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Chong Zhangd291c222015-04-30 18:15:52 -0700206
Chong Zhangaddf2cb2016-09-28 17:53:01 -0700207 data.writeStrongBinder(IInterface::asBinder(bufferSource));
208
209 status_t err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700210
211 if (err != OK) {
212 ALOGW("binder transaction failed: %d", err);
213 return err;
214 }
Lajos Molnar05421982015-05-15 20:39:14 -0700215
Chong Zhang6d332d22016-09-07 12:06:50 -0700216 err = reply.readInt32();
Chong Zhang6d332d22016-09-07 12:06:50 -0700217
218 return err;
Andy McFadden7cd58532013-02-19 07:28:30 -0800219 }
220
Lajos Molnar56ce7262013-05-02 16:30:48 -0700221 virtual status_t prepareForAdaptivePlayback(
Chong Zhangd59b9722016-09-20 16:31:18 -0700222 OMX_U32 port_index, OMX_BOOL enable,
Lajos Molnar56ce7262013-05-02 16:30:48 -0700223 OMX_U32 max_width, OMX_U32 max_height) {
224 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700225 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Lajos Molnar56ce7262013-05-02 16:30:48 -0700226 data.writeInt32(port_index);
227 data.writeInt32((int32_t)enable);
228 data.writeInt32(max_width);
229 data.writeInt32(max_height);
230 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
231
232 status_t err = reply.readInt32();
233 return err;
234 }
235
Rachad5a446aa2014-07-29 16:47:56 -0700236 virtual status_t configureVideoTunnelMode(
Chong Zhangd59b9722016-09-20 16:31:18 -0700237 OMX_U32 portIndex, OMX_BOOL tunneled,
Rachad5a446aa2014-07-29 16:47:56 -0700238 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
239 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700240 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Rachad5a446aa2014-07-29 16:47:56 -0700241 data.writeInt32(portIndex);
242 data.writeInt32((int32_t)tunneled);
243 data.writeInt32(audioHwSync);
244 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
245
246 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800247 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700248 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
249 }
250 return err;
251 }
252
253
Lajos Molnara63141a2016-02-11 16:40:36 -0800254 virtual status_t allocateSecureBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700255 OMX_U32 port_index, size_t size,
Lajos Molnar1b40f282016-05-09 22:24:52 -0700256 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700257 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700258 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber20111aa2009-07-14 16:56:47 -0700259 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800260 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800261 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700262
263 status_t err = reply.readInt32();
264 if (err != OK) {
265 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800266 *buffer_data = NULL;
267 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700268 return err;
269 }
270
Andy Hung609b8152014-05-02 11:05:04 -0700271 *buffer = (buffer_id)reply.readInt32();
272 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800273 if (*buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -0700274 *native_handle = NativeHandle::create(
275 reply.readNativeHandle(), true /* ownsHandle */);
Lajos Molnara63141a2016-02-11 16:40:36 -0800276 } else {
277 *native_handle = NULL;
278 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700279 return err;
280 }
281
Andreas Huber318ad9c2009-10-15 13:46:54 -0700282 virtual status_t freeBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700283 OMX_U32 port_index, buffer_id buffer) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700284 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700285 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber20111aa2009-07-14 16:56:47 -0700286 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700287 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700288 remote()->transact(FREE_BUFFER, data, &reply);
289
290 return reply.readInt32();
291 }
292
Chong Zhang3fd200f2016-10-07 17:25:58 -0700293 virtual status_t fillBuffer(
294 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700295 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700296 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700297 data.writeInt32((int32_t)buffer);
Chong Zhang3fd200f2016-10-07 17:25:58 -0700298 status_t err = omxBuf.writeToParcel(&data);
299 if (err != OK) {
300 return err;
301 }
Lajos Molnar15ab4992015-06-01 10:54:31 -0700302 data.writeInt32(fenceFd >= 0);
303 if (fenceFd >= 0) {
304 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
305 }
Andreas Huber36efa032009-10-08 11:02:27 -0700306 remote()->transact(FILL_BUFFER, data, &reply);
307
308 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700309 }
310
Andreas Huber318ad9c2009-10-15 13:46:54 -0700311 virtual status_t emptyBuffer(
Chong Zhang3fd200f2016-10-07 17:25:58 -0700312 buffer_id buffer, const OMXBuffer &omxBuf,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700313 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700314 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700315 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700316 data.writeInt32((int32_t)buffer);
Chong Zhang3fd200f2016-10-07 17:25:58 -0700317 status_t err = omxBuf.writeToParcel(&data);
318 if (err != OK) {
319 return err;
320 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700321 data.writeInt32(flags);
322 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700323 data.writeInt32(fenceFd >= 0);
324 if (fenceFd >= 0) {
325 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
326 }
Andreas Huber36efa032009-10-08 11:02:27 -0700327 remote()->transact(EMPTY_BUFFER, data, &reply);
328
329 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700330 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700331
Andreas Huber318ad9c2009-10-15 13:46:54 -0700332 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700333 const char *parameter_name,
334 OMX_INDEXTYPE *index) {
335 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700336 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Andreas Huber693d2712009-08-14 14:37:10 -0700337 data.writeCString(parameter_name);
338
339 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
340
341 status_t err = reply.readInt32();
342 if (err == OK) {
343 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
344 } else {
345 *index = OMX_IndexComponentStartUnused;
346 }
347
348 return err;
349 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700350
Chong Zhang6cf9a122016-09-08 23:25:52 -0700351 virtual status_t dispatchMessage(const omx_message &msg) {
352 Parcel data, reply;
Chong Zhangd59b9722016-09-20 16:31:18 -0700353 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
Chong Zhang6cf9a122016-09-08 23:25:52 -0700354 data.writeInt32(msg.fenceFd >= 0);
355 if (msg.fenceFd >= 0) {
356 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
357 }
358 data.writeInt32(msg.type);
359 data.write(&msg.u, sizeof(msg.u));
360
361 remote()->transact(DISPATCH_MESSAGE, data, &reply);
362
363 return reply.readInt32();
364 }
Chong Zhang21b46582016-10-04 12:44:53 -0700365
366 virtual status_t setQuirks(OMX_U32 quirks) {
367 Parcel data, reply;
368 data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
369 data.writeInt32(quirks);
370
371 remote()->transact(SET_QUIRKS, data, &reply);
372
373 return reply.readInt32();
374 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700375};
376
Pawin Vongmasaac7d4122017-03-01 05:48:42 -0800377using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
378class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> {
379public:
380 HpOMXNode(const sp<IBinder>& base) : PBase(base) {}
381
382 virtual status_t freeNode() {
383 return mBase->freeNode();
384 }
385
386 virtual status_t sendCommand(
387 OMX_COMMANDTYPE cmd, OMX_S32 param) {
388 return mBase->sendCommand(cmd, param);
389 }
390
391 virtual status_t getParameter(
392 OMX_INDEXTYPE index, void *params, size_t size) {
393 return mBase->getParameter(index, params, size);
394 }
395
396 virtual status_t setParameter(
397 OMX_INDEXTYPE index, const void *params, size_t size) {
398 return mBase->setParameter(index, params, size);
399 }
400
401 virtual status_t getConfig(
402 OMX_INDEXTYPE index, void *params, size_t size) {
403 return mBase->getConfig(index, params, size);
404 }
405
406 virtual status_t setConfig(
407 OMX_INDEXTYPE index, const void *params, size_t size) {
408 return mBase->setConfig(index, params, size);
409 }
410
411 virtual status_t setPortMode(
412 OMX_U32 port_index, IOMX::PortMode mode) {
413 return mBase->setPortMode(port_index, mode);
414 }
415
416 virtual status_t prepareForAdaptivePlayback(
417 OMX_U32 portIndex, OMX_BOOL enable,
418 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
419 return mBase->prepareForAdaptivePlayback(
420 portIndex, enable, maxFrameWidth, maxFrameHeight);
421 }
422
423 virtual status_t configureVideoTunnelMode(
424 OMX_U32 portIndex, OMX_BOOL tunneled,
425 OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
426 return mBase->configureVideoTunnelMode(
427 portIndex, tunneled, audioHwSync, sidebandHandle);
428 }
429
430 virtual status_t getGraphicBufferUsage(
431 OMX_U32 port_index, OMX_U32* usage) {
432 return mBase->getGraphicBufferUsage(port_index, usage);
433 }
434
435 virtual status_t setInputSurface(
436 const sp<IOMXBufferSource> &bufferSource) {
437 return mBase->setInputSurface(bufferSource);
438 }
439
440 virtual status_t allocateSecureBuffer(
441 OMX_U32 port_index, size_t size, buffer_id *buffer,
442 void **buffer_data, sp<NativeHandle> *native_handle) {
443 return mBase->allocateSecureBuffer(
444 port_index, size, buffer, buffer_data, native_handle);
445 }
446
447 virtual status_t useBuffer(
448 OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
449 return mBase->useBuffer(port_index, omxBuf, buffer);
450 }
451
452 virtual status_t freeBuffer(
453 OMX_U32 port_index, buffer_id buffer) {
454 return mBase->freeBuffer(port_index, buffer);
455 }
456
457 virtual status_t fillBuffer(
458 buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) {
459 return mBase->fillBuffer(buffer, omxBuf, fenceFd);
460 }
461
462 virtual status_t emptyBuffer(
463 buffer_id buffer, const OMXBuffer &omxBuf,
464 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) {
465 return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
466 }
467
468 virtual status_t getExtensionIndex(
469 const char *parameter_name,
470 OMX_INDEXTYPE *index) {
471 return mBase->getExtensionIndex(parameter_name, index);
472 }
473
474 virtual status_t dispatchMessage(const omx_message &msg) {
475 return mBase->dispatchMessage(msg);
476 }
Pawin Vongmasaac7d4122017-03-01 05:48:42 -0800477};
478
Pawin Vongmasa3866c7e2019-01-31 05:21:29 -0800479IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
Andreas Huber20111aa2009-07-14 16:56:47 -0700480
481////////////////////////////////////////////////////////////////////////////////
482
Andy McFadden7cd58532013-02-19 07:28:30 -0800483#define CHECK_OMX_INTERFACE(interface, data, reply) \
Chih-Hung Hsieh83fbbb82016-05-17 15:08:10 -0700484 do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000485 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700486 return PERMISSION_DENIED; \
487 } } while (0)
488
Chong Zhangd59b9722016-09-20 16:31:18 -0700489status_t BnOMXNode::onTransact(
490 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
491 switch (code) {
492 case FREE_NODE:
493 {
494 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
495
496 reply->writeInt32(freeNode());
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800497
Andreas Huber20111aa2009-07-14 16:56:47 -0700498 return NO_ERROR;
499 }
500
501 case SEND_COMMAND:
502 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700503 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700504
505 OMX_COMMANDTYPE cmd =
506 static_cast<OMX_COMMANDTYPE>(data.readInt32());
507
508 OMX_S32 param = data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700509 reply->writeInt32(sendCommand(cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700510
511 return NO_ERROR;
512 }
513
514 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700515 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700516 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700517 case SET_CONFIG:
518 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700519 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700520
Andreas Huber693d2712009-08-14 14:37:10 -0700521 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
522
Glenn Kastene03dd222014-01-28 11:04:39 -0800523 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700524
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800525 status_t err = NOT_ENOUGH_DATA;
526 void *params = NULL;
527 size_t pageSize = 0;
528 size_t allocSize = 0;
Marco Nelissen788b0b62016-03-21 11:31:53 -0700529 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
Chong Zhang6d332d22016-09-07 12:06:50 -0700530 if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800531 // we expect the structure to contain at least the size and
532 // version, 8 bytes total
Marco Nelissen788b0b62016-03-21 11:31:53 -0700533 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800534 android_errorWriteLog(0x534e4554, "27207275");
535 } else {
536 err = NO_MEMORY;
537 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
538 if (size > SIZE_MAX - (pageSize * 2)) {
539 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800540 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800541 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
542 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
543 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
544 }
Caroline Tice225fc692016-11-15 18:03:48 -0800545 if (params != MAP_FAILED && params != NULL) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800546 err = data.read(params, size);
547 if (err != OK) {
548 android_errorWriteLog(0x534e4554, "26914474");
549 } else {
550 err = NOT_ENOUGH_DATA;
551 OMX_U32 declaredSize = *(OMX_U32*)params;
Chong Zhang6d332d22016-09-07 12:06:50 -0700552 if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
Marco Nelissenc1c50e72016-03-10 15:02:13 -0800553 declaredSize > size) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800554 // the buffer says it's bigger than it actually is
555 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
556 android_errorWriteLog(0x534e4554, "27207275");
557 } else {
558 // mark the last page as inaccessible, to avoid exploitation
559 // of codecs that access past the end of the allocation because
560 // they didn't check the size
Marco Nelissen866c8002016-09-20 13:36:40 -0700561 if (mprotect((char*)params + allocSize - pageSize, pageSize,
562 PROT_NONE) != 0) {
563 ALOGE("mprotect failed: %s", strerror(errno));
564 } else {
565 switch (code) {
566 case GET_PARAMETER:
Chong Zhangd59b9722016-09-20 16:31:18 -0700567 err = getParameter(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700568 break;
569 case SET_PARAMETER:
Chong Zhangd59b9722016-09-20 16:31:18 -0700570 err = setParameter(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700571 break;
572 case GET_CONFIG:
Chong Zhangd59b9722016-09-20 16:31:18 -0700573 err = getConfig(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700574 break;
575 case SET_CONFIG:
Chong Zhangd59b9722016-09-20 16:31:18 -0700576 err = setConfig(index, params, size);
Marco Nelissen866c8002016-09-20 13:36:40 -0700577 break;
Marco Nelissen866c8002016-09-20 13:36:40 -0700578 default:
579 TRESPASS();
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800580 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800581 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800582 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800583 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800584 } else {
585 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700586 }
Andreas Huberb3912902011-01-19 10:34:52 -0800587 }
588
589 reply->writeInt32(err);
590
591 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
592 reply->write(params, size);
593 }
594
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800595 if (params) {
596 munmap(params, allocSize);
597 }
Andreas Huberb3912902011-01-19 10:34:52 -0800598 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700599
600 return NO_ERROR;
601 }
602
Chong Zhangd02c0862016-10-13 14:32:32 -0700603 case SET_PORT_MODE:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700604 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700605 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700606 OMX_U32 port_index = data.readInt32();
Chong Zhangd02c0862016-10-13 14:32:32 -0700607 IOMX::PortMode mode = (IOMX::PortMode) data.readInt32();
608 reply->writeInt32(setPortMode(port_index, mode));
Jamie Gennis83750ea2010-08-30 16:48:38 -0700609
610 return NO_ERROR;
611 }
612
Jamie Gennise2ce6452011-02-23 19:01:28 -0800613 case GET_GRAPHIC_BUFFER_USAGE:
614 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700615 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800616
Jamie Gennise2ce6452011-02-23 19:01:28 -0800617 OMX_U32 port_index = data.readInt32();
618
619 OMX_U32 usage = 0;
Chong Zhangd59b9722016-09-20 16:31:18 -0700620 status_t err = getGraphicBufferUsage(port_index, &usage);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800621 reply->writeInt32(err);
622 reply->writeInt32(usage);
623
624 return NO_ERROR;
625 }
626
Andreas Huber20111aa2009-07-14 16:56:47 -0700627 case USE_BUFFER:
628 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700629 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700630
Andreas Huber20111aa2009-07-14 16:56:47 -0700631 OMX_U32 port_index = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700632
Chong Zhang3fd200f2016-10-07 17:25:58 -0700633 OMXBuffer omxBuf;
634 status_t err = omxBuf.readFromParcel(&data);
635 if (err != OK) {
636 return err;
Wei Jia56c95c92016-01-06 10:30:46 -0800637 }
638
Andreas Huber20111aa2009-07-14 16:56:47 -0700639 buffer_id buffer;
Chong Zhang3fd200f2016-10-07 17:25:58 -0700640 err = useBuffer(port_index, omxBuf, &buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700641 reply->writeInt32(err);
642
643 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700644 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700645 }
646
647 return NO_ERROR;
648 }
649
Chong Zhang8f469e12015-05-13 10:21:33 -0700650 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700651 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700652 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700653
Chong Zhangaddf2cb2016-09-28 17:53:01 -0700654 sp<IOMXBufferSource> bufferSource =
655 interface_cast<IOMXBufferSource>(data.readStrongBinder());
Chong Zhangd291c222015-04-30 18:15:52 -0700656
Chong Zhangaddf2cb2016-09-28 17:53:01 -0700657 status_t err = setInputSurface(bufferSource);
Chong Zhangd291c222015-04-30 18:15:52 -0700658 reply->writeInt32(err);
Chong Zhangaddf2cb2016-09-28 17:53:01 -0700659
Andy McFadden7cd58532013-02-19 07:28:30 -0800660 return NO_ERROR;
661 }
662
Lajos Molnar56ce7262013-05-02 16:30:48 -0700663 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
664 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700665 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700666
Lajos Molnar56ce7262013-05-02 16:30:48 -0700667 OMX_U32 port_index = data.readInt32();
668 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
669 OMX_U32 max_width = data.readInt32();
670 OMX_U32 max_height = data.readInt32();
671
672 status_t err = prepareForAdaptivePlayback(
Chong Zhangd59b9722016-09-20 16:31:18 -0700673 port_index, enable, max_width, max_height);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700674 reply->writeInt32(err);
675
676 return NO_ERROR;
677 }
678
Rachad5a446aa2014-07-29 16:47:56 -0700679 case CONFIGURE_VIDEO_TUNNEL_MODE:
680 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700681 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Rachad5a446aa2014-07-29 16:47:56 -0700682
Rachad5a446aa2014-07-29 16:47:56 -0700683 OMX_U32 port_index = data.readInt32();
684 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
685 OMX_U32 audio_hw_sync = data.readInt32();
686
Lajos Molnara63141a2016-02-11 16:40:36 -0800687 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -0700688 status_t err = configureVideoTunnelMode(
Chong Zhangd59b9722016-09-20 16:31:18 -0700689 port_index, tunneled, audio_hw_sync, &sideband_handle);
Rachad5a446aa2014-07-29 16:47:56 -0700690 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -0800691 if(err == OK){
692 reply->writeNativeHandle(sideband_handle);
693 }
Rachad5a446aa2014-07-29 16:47:56 -0700694
695 return NO_ERROR;
696 }
697
Lajos Molnara63141a2016-02-11 16:40:36 -0800698 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700699 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700700 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700701
Andreas Huber20111aa2009-07-14 16:56:47 -0700702 OMX_U32 port_index = data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700703 if (!isSecure() || port_index != 0 /* kPortIndexInput */) {
Wei Jia8dde7262015-09-28 11:32:23 -0700704 ALOGE("b/24310423");
705 reply->writeInt32(INVALID_OPERATION);
706 return NO_ERROR;
707 }
708
Glenn Kastene03dd222014-01-28 11:04:39 -0800709 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -0700710
711 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -0800712 void *buffer_data = NULL;
Lajos Molnar1b40f282016-05-09 22:24:52 -0700713 sp<NativeHandle> native_handle;
Lajos Molnara63141a2016-02-11 16:40:36 -0800714 status_t err = allocateSecureBuffer(
Chong Zhangd59b9722016-09-20 16:31:18 -0700715 port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -0700716 reply->writeInt32(err);
717
718 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700719 reply->writeInt32((int32_t)buffer);
720 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -0800721 if (buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -0700722 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
Lajos Molnara63141a2016-02-11 16:40:36 -0800723 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700724 }
725
726 return NO_ERROR;
727 }
728
Andreas Huber20111aa2009-07-14 16:56:47 -0700729 case FREE_BUFFER:
730 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700731 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700732
Andreas Huber20111aa2009-07-14 16:56:47 -0700733 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -0700734 buffer_id buffer = (buffer_id)data.readInt32();
Chong Zhangd59b9722016-09-20 16:31:18 -0700735 reply->writeInt32(freeBuffer(port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700736
737 return NO_ERROR;
738 }
739
740 case FILL_BUFFER:
741 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700742 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700743
Andy Hung609b8152014-05-02 11:05:04 -0700744 buffer_id buffer = (buffer_id)data.readInt32();
Chong Zhang3fd200f2016-10-07 17:25:58 -0700745
746 OMXBuffer omxBuf;
747 status_t err = omxBuf.readFromParcel(&data);
748 if (err != OK) {
749 return err;
750 }
751
Lajos Molnar15ab4992015-06-01 10:54:31 -0700752 bool haveFence = data.readInt32();
753 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
Chong Zhang3fd200f2016-10-07 17:25:58 -0700754
755 reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -0700756
757 return NO_ERROR;
758 }
759
760 case EMPTY_BUFFER:
761 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700762 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700763
Andy Hung609b8152014-05-02 11:05:04 -0700764 buffer_id buffer = (buffer_id)data.readInt32();
Chong Zhang3fd200f2016-10-07 17:25:58 -0700765 OMXBuffer omxBuf;
766 status_t err = omxBuf.readFromParcel(&data);
767 if (err != OK) {
768 return err;
769 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700770 OMX_U32 flags = data.readInt32();
771 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -0700772 bool haveFence = data.readInt32();
773 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
774 reply->writeInt32(emptyBuffer(
Chong Zhang3fd200f2016-10-07 17:25:58 -0700775 buffer, omxBuf, flags, timestamp, fenceFd));
Chong Zhang6cf9a122016-09-08 23:25:52 -0700776
777 return NO_ERROR;
778 }
779
Andreas Huber693d2712009-08-14 14:37:10 -0700780 case GET_EXTENSION_INDEX:
781 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700782 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700783
Andreas Huber693d2712009-08-14 14:37:10 -0700784 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800785
Wei Jia56c95c92016-01-06 10:30:46 -0800786 if (parameter_name == NULL) {
787 ALOGE("b/26392700");
788 reply->writeInt32(INVALID_OPERATION);
789 return NO_ERROR;
790 }
791
Andreas Huber693d2712009-08-14 14:37:10 -0700792 OMX_INDEXTYPE index;
Chong Zhangd59b9722016-09-20 16:31:18 -0700793 status_t err = getExtensionIndex(parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -0700794
795 reply->writeInt32(err);
796
797 if (err == OK) {
798 reply->writeInt32(index);
799 }
800
801 return OK;
802 }
803
Chong Zhang6cf9a122016-09-08 23:25:52 -0700804 case DISPATCH_MESSAGE:
805 {
Chong Zhangd59b9722016-09-20 16:31:18 -0700806 CHECK_OMX_INTERFACE(IOMXNode, data, reply);
Chong Zhang6cf9a122016-09-08 23:25:52 -0700807 omx_message msg;
Chong Zhang6cf9a122016-09-08 23:25:52 -0700808 int haveFence = data.readInt32();
809 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
810 msg.type = (typeof(msg.type))data.readInt32();
811 status_t err = data.read(&msg.u, sizeof(msg.u));
812
813 if (err == OK) {
814 err = dispatchMessage(msg);
815 }
816 reply->writeInt32(err);
817
818 return NO_ERROR;
819 }
820
Andreas Huber20111aa2009-07-14 16:56:47 -0700821 default:
822 return BBinder::onTransact(code, data, reply, flags);
823 }
824}
825
826////////////////////////////////////////////////////////////////////////////////
827
828class BpOMXObserver : public BpInterface<IOMXObserver> {
829public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700830 explicit BpOMXObserver(const sp<IBinder> &impl)
Andreas Huber20111aa2009-07-14 16:56:47 -0700831 : BpInterface<IOMXObserver>(impl) {
832 }
833
Lajos Molnar26a48f32015-06-04 10:30:02 -0700834 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700835 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -0700836 std::list<omx_message>::const_iterator it = messages.cbegin();
Chong Zhangd59b9722016-09-20 16:31:18 -0700837 if (messages.empty()) {
838 return;
839 }
840 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
Lajos Molnar26a48f32015-06-04 10:30:02 -0700841 while (it != messages.cend()) {
842 const omx_message &msg = *it++;
Lajos Molnar26a48f32015-06-04 10:30:02 -0700843 data.writeInt32(msg.fenceFd >= 0);
844 if (msg.fenceFd >= 0) {
845 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
846 }
847 data.writeInt32(msg.type);
848 data.write(&msg.u, sizeof(msg.u));
849 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -0700850 }
Chong Zhangd59b9722016-09-20 16:31:18 -0700851 data.writeInt32(-1); // mark end
852 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
Andreas Huber20111aa2009-07-14 16:56:47 -0700853 }
854};
855
856IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
857
858status_t BnOMXObserver::onTransact(
859 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
860 switch (code) {
861 case OBSERVER_ON_MSG:
862 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800863 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -0700864 std::list<omx_message> messages;
865 status_t err = FAILED_TRANSACTION; // must receive at least one message
866 do {
867 int haveFence = data.readInt32();
868 if (haveFence < 0) { // we use -1 to mark end of messages
869 break;
870 }
871 omx_message msg;
Lajos Molnar26a48f32015-06-04 10:30:02 -0700872 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
873 msg.type = (typeof(msg.type))data.readInt32();
874 err = data.read(&msg.u, sizeof(msg.u));
875 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
876 messages.push_back(msg);
877 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -0700878
Lajos Molnar26a48f32015-06-04 10:30:02 -0700879 if (err == OK) {
880 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700881 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700882
Lajos Molnar26a48f32015-06-04 10:30:02 -0700883 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -0700884 }
885
886 default:
887 return BBinder::onTransact(code, data, reply, flags);
888 }
889}
890
Andreas Huber20111aa2009-07-14 16:56:47 -0700891} // namespace android