1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18 #include <sys/types.h>
19
20 #include <utils/Errors.h>
21 #include <utils/NativeHandle.h>
22 #include <utils/RefBase.h>
23 #include <utils/Timers.h>
24 #include <utils/Vector.h>
25
26 #include <binder/Parcel.h>
27 #include <binder/IInterface.h>
28
29 #include <gui/BufferQueueDefs.h>
30 #include <gui/IGraphicBufferProducer.h>
31 #include <gui/IProducerListener.h>
32
33 namespace android {
34 // ----------------------------------------------------------------------------
35
36 enum {
37 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
38 DEQUEUE_BUFFER,
39 DETACH_BUFFER,
40 DETACH_NEXT_BUFFER,
41 ATTACH_BUFFER,
42 QUEUE_BUFFER,
43 CANCEL_BUFFER,
44 QUERY,
45 CONNECT,
46 DISCONNECT,
47 SET_SIDEBAND_STREAM,
48 ALLOCATE_BUFFERS,
49 ALLOW_ALLOCATION,
50 SET_GENERATION_NUMBER,
51 GET_CONSUMER_NAME,
52 SET_MAX_DEQUEUED_BUFFER_COUNT,
53 SET_ASYNC_MODE,
54 SET_SHARED_BUFFER_MODE,
55 SET_AUTO_REFRESH,
56 SET_DEQUEUE_TIMEOUT,
57 GET_LAST_QUEUED_BUFFER,
58 GET_FRAME_TIMESTAMPS,
59 GET_UNIQUE_ID
60 };
61
62 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
63 {
64 public:
BpGraphicBufferProducer(const sp<IBinder> & impl)65 BpGraphicBufferProducer(const sp<IBinder>& impl)
66 : BpInterface<IGraphicBufferProducer>(impl)
67 {
68 }
69
70 virtual ~BpGraphicBufferProducer();
71
requestBuffer(int bufferIdx,sp<GraphicBuffer> * buf)72 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
73 Parcel data, reply;
74 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
75 data.writeInt32(bufferIdx);
76 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
77 if (result != NO_ERROR) {
78 return result;
79 }
80 bool nonNull = reply.readInt32();
81 if (nonNull) {
82 *buf = new GraphicBuffer();
83 result = reply.read(**buf);
84 if(result != NO_ERROR) {
85 (*buf).clear();
86 return result;
87 }
88 }
89 result = reply.readInt32();
90 return result;
91 }
92
setMaxDequeuedBufferCount(int maxDequeuedBuffers)93 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
94 Parcel data, reply;
95 data.writeInterfaceToken(
96 IGraphicBufferProducer::getInterfaceDescriptor());
97 data.writeInt32(maxDequeuedBuffers);
98 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT,
99 data, &reply);
100 if (result != NO_ERROR) {
101 return result;
102 }
103 result = reply.readInt32();
104 return result;
105 }
106
setAsyncMode(bool async)107 virtual status_t setAsyncMode(bool async) {
108 Parcel data, reply;
109 data.writeInterfaceToken(
110 IGraphicBufferProducer::getInterfaceDescriptor());
111 data.writeInt32(async);
112 status_t result = remote()->transact(SET_ASYNC_MODE,
113 data, &reply);
114 if (result != NO_ERROR) {
115 return result;
116 }
117 result = reply.readInt32();
118 return result;
119 }
120
dequeueBuffer(int * buf,sp<Fence> * fence,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)121 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
122 uint32_t height, PixelFormat format, uint32_t usage) {
123 Parcel data, reply;
124 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
125 data.writeUint32(width);
126 data.writeUint32(height);
127 data.writeInt32(static_cast<int32_t>(format));
128 data.writeUint32(usage);
129 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
130 if (result != NO_ERROR) {
131 return result;
132 }
133 *buf = reply.readInt32();
134 bool nonNull = reply.readInt32();
135 if (nonNull) {
136 *fence = new Fence();
137 result = reply.read(**fence);
138 if (result != NO_ERROR) {
139 fence->clear();
140 return result;
141 }
142 }
143 result = reply.readInt32();
144 return result;
145 }
146
detachBuffer(int slot)147 virtual status_t detachBuffer(int slot) {
148 Parcel data, reply;
149 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
150 data.writeInt32(slot);
151 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
152 if (result != NO_ERROR) {
153 return result;
154 }
155 result = reply.readInt32();
156 return result;
157 }
158
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)159 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
160 sp<Fence>* outFence) {
161 if (outBuffer == NULL) {
162 ALOGE("detachNextBuffer: outBuffer must not be NULL");
163 return BAD_VALUE;
164 } else if (outFence == NULL) {
165 ALOGE("detachNextBuffer: outFence must not be NULL");
166 return BAD_VALUE;
167 }
168 Parcel data, reply;
169 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
170 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
171 if (result != NO_ERROR) {
172 return result;
173 }
174 result = reply.readInt32();
175 if (result == NO_ERROR) {
176 bool nonNull = reply.readInt32();
177 if (nonNull) {
178 *outBuffer = new GraphicBuffer;
179 result = reply.read(**outBuffer);
180 if (result != NO_ERROR) {
181 outBuffer->clear();
182 return result;
183 }
184 }
185 nonNull = reply.readInt32();
186 if (nonNull) {
187 *outFence = new Fence;
188 result = reply.read(**outFence);
189 if (result != NO_ERROR) {
190 outBuffer->clear();
191 outFence->clear();
192 return result;
193 }
194 }
195 }
196 return result;
197 }
198
attachBuffer(int * slot,const sp<GraphicBuffer> & buffer)199 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
200 Parcel data, reply;
201 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
202 data.write(*buffer.get());
203 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
204 if (result != NO_ERROR) {
205 return result;
206 }
207
208 *slot = reply.readInt32();
209 result = reply.readInt32();
210 if (result == NO_ERROR &&
211 (*slot < 0 || *slot >= BufferQueueDefs::NUM_BUFFER_SLOTS)) {
212 ALOGE("attachBuffer returned invalid slot %d", *slot);
213 android_errorWriteLog(0x534e4554, "37478824");
214 return UNKNOWN_ERROR;
215 }
216
217 return result;
218 }
219
queueBuffer(int buf,const QueueBufferInput & input,QueueBufferOutput * output)220 virtual status_t queueBuffer(int buf,
221 const QueueBufferInput& input, QueueBufferOutput* output) {
222 Parcel data, reply;
223 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
224 data.writeInt32(buf);
225 data.write(input);
226 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
227 if (result != NO_ERROR) {
228 return result;
229 }
230 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
231 result = reply.readInt32();
232 return result;
233 }
234
cancelBuffer(int buf,const sp<Fence> & fence)235 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
236 Parcel data, reply;
237 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
238 data.writeInt32(buf);
239 data.write(*fence.get());
240 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
241 if (result != NO_ERROR) {
242 return result;
243 }
244 result = reply.readInt32();
245 return result;
246 }
247
query(int what,int * value)248 virtual int query(int what, int* value) {
249 Parcel data, reply;
250 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
251 data.writeInt32(what);
252 status_t result = remote()->transact(QUERY, data, &reply);
253 if (result != NO_ERROR) {
254 return result;
255 }
256 value[0] = reply.readInt32();
257 result = reply.readInt32();
258 return result;
259 }
260
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)261 virtual status_t connect(const sp<IProducerListener>& listener,
262 int api, bool producerControlledByApp, QueueBufferOutput* output) {
263 Parcel data, reply;
264 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
265 if (listener != NULL) {
266 data.writeInt32(1);
267 data.writeStrongBinder(IInterface::asBinder(listener));
268 } else {
269 data.writeInt32(0);
270 }
271 data.writeInt32(api);
272 data.writeInt32(producerControlledByApp);
273 status_t result = remote()->transact(CONNECT, data, &reply);
274 if (result != NO_ERROR) {
275 return result;
276 }
277 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
278 result = reply.readInt32();
279 return result;
280 }
281
disconnect(int api,DisconnectMode mode)282 virtual status_t disconnect(int api, DisconnectMode mode) {
283 Parcel data, reply;
284 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
285 data.writeInt32(api);
286 data.writeInt32(static_cast<int32_t>(mode));
287 status_t result =remote()->transact(DISCONNECT, data, &reply);
288 if (result != NO_ERROR) {
289 return result;
290 }
291 result = reply.readInt32();
292 return result;
293 }
294
setSidebandStream(const sp<NativeHandle> & stream)295 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
296 Parcel data, reply;
297 status_t result;
298 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
299 if (stream.get()) {
300 data.writeInt32(true);
301 data.writeNativeHandle(stream->handle());
302 } else {
303 data.writeInt32(false);
304 }
305 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
306 result = reply.readInt32();
307 }
308 return result;
309 }
310
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)311 virtual void allocateBuffers(uint32_t width, uint32_t height,
312 PixelFormat format, uint32_t usage) {
313 Parcel data, reply;
314 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
315 data.writeUint32(width);
316 data.writeUint32(height);
317 data.writeInt32(static_cast<int32_t>(format));
318 data.writeUint32(usage);
319 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
320 if (result != NO_ERROR) {
321 ALOGE("allocateBuffers failed to transact: %d", result);
322 }
323 }
324
allowAllocation(bool allow)325 virtual status_t allowAllocation(bool allow) {
326 Parcel data, reply;
327 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
328 data.writeInt32(static_cast<int32_t>(allow));
329 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
330 if (result != NO_ERROR) {
331 return result;
332 }
333 result = reply.readInt32();
334 return result;
335 }
336
setGenerationNumber(uint32_t generationNumber)337 virtual status_t setGenerationNumber(uint32_t generationNumber) {
338 Parcel data, reply;
339 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
340 data.writeUint32(generationNumber);
341 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
342 if (result == NO_ERROR) {
343 result = reply.readInt32();
344 }
345 return result;
346 }
347
getConsumerName() const348 virtual String8 getConsumerName() const {
349 Parcel data, reply;
350 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
351 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
352 if (result != NO_ERROR) {
353 ALOGE("getConsumerName failed to transact: %d", result);
354 return String8("TransactFailed");
355 }
356 return reply.readString8();
357 }
358
setSharedBufferMode(bool sharedBufferMode)359 virtual status_t setSharedBufferMode(bool sharedBufferMode) {
360 Parcel data, reply;
361 data.writeInterfaceToken(
362 IGraphicBufferProducer::getInterfaceDescriptor());
363 data.writeInt32(sharedBufferMode);
364 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data,
365 &reply);
366 if (result == NO_ERROR) {
367 result = reply.readInt32();
368 }
369 return result;
370 }
371
setAutoRefresh(bool autoRefresh)372 virtual status_t setAutoRefresh(bool autoRefresh) {
373 Parcel data, reply;
374 data.writeInterfaceToken(
375 IGraphicBufferProducer::getInterfaceDescriptor());
376 data.writeInt32(autoRefresh);
377 status_t result = remote()->transact(SET_AUTO_REFRESH, data, &reply);
378 if (result == NO_ERROR) {
379 result = reply.readInt32();
380 }
381 return result;
382 }
383
setDequeueTimeout(nsecs_t timeout)384 virtual status_t setDequeueTimeout(nsecs_t timeout) {
385 Parcel data, reply;
386 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
387 data.writeInt64(timeout);
388 status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply);
389 if (result != NO_ERROR) {
390 ALOGE("setDequeueTimeout failed to transact: %d", result);
391 return result;
392 }
393 return reply.readInt32();
394 }
395
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])396 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
397 sp<Fence>* outFence, float outTransformMatrix[16]) override {
398 Parcel data, reply;
399 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
400 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data,
401 &reply);
402 if (result != NO_ERROR) {
403 ALOGE("getLastQueuedBuffer failed to transact: %d", result);
404 return result;
405 }
406 result = reply.readInt32();
407 if (result != NO_ERROR) {
408 return result;
409 }
410 bool hasBuffer = reply.readBool();
411 sp<GraphicBuffer> buffer;
412 if (hasBuffer) {
413 buffer = new GraphicBuffer();
414 result = reply.read(*buffer);
415 if (result == NO_ERROR) {
416 result = reply.read(outTransformMatrix, sizeof(float) * 16);
417 }
418 }
419 if (result != NO_ERROR) {
420 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result);
421 return result;
422 }
423 sp<Fence> fence(new Fence);
424 result = reply.read(*fence);
425 if (result != NO_ERROR) {
426 ALOGE("getLastQueuedBuffer failed to read fence: %d", result);
427 return result;
428 }
429 *outBuffer = buffer;
430 *outFence = fence;
431 return result;
432 }
433
getFrameTimestamps(uint64_t frameNumber,FrameTimestamps * outTimestamps) const434 virtual bool getFrameTimestamps(uint64_t frameNumber,
435 FrameTimestamps* outTimestamps) const {
436 Parcel data, reply;
437 status_t result = data.writeInterfaceToken(
438 IGraphicBufferProducer::getInterfaceDescriptor());
439 if (result != NO_ERROR) {
440 ALOGE("getFrameTimestamps failed to write token: %d", result);
441 return false;
442 }
443 result = data.writeUint64(frameNumber);
444 if (result != NO_ERROR) {
445 ALOGE("getFrameTimestamps failed to write: %d", result);
446 return false;
447 }
448 result = remote()->transact(GET_FRAME_TIMESTAMPS, data, &reply);
449 if (result != NO_ERROR) {
450 ALOGE("getFrameTimestamps failed to transact: %d", result);
451 return false;
452 }
453 bool found = false;
454 result = reply.readBool(&found);
455 if (result != NO_ERROR) {
456 ALOGE("getFrameTimestamps failed to read: %d", result);
457 return false;
458 }
459 if (found) {
460 result = reply.read(*outTimestamps);
461 if (result != NO_ERROR) {
462 ALOGE("getFrameTimestamps failed to read timestamps: %d",
463 result);
464 return false;
465 }
466 }
467 return found;
468 }
469
getUniqueId(uint64_t * outId) const470 virtual status_t getUniqueId(uint64_t* outId) const {
471 Parcel data, reply;
472 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
473 status_t result = remote()->transact(GET_UNIQUE_ID, data, &reply);
474 if (result != NO_ERROR) {
475 ALOGE("getUniqueId failed to transact: %d", result);
476 }
477 status_t actualResult = NO_ERROR;
478 result = reply.readInt32(&actualResult);
479 if (result != NO_ERROR) {
480 return result;
481 }
482 result = reply.readUint64(outId);
483 if (result != NO_ERROR) {
484 return result;
485 }
486 return actualResult;
487 }
488 };
489
490 // Out-of-line virtual method definition to trigger vtable emission in this
491 // translation unit (see clang warning -Wweak-vtables)
~BpGraphicBufferProducer()492 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
493
494 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
495
496 // ----------------------------------------------------------------------
497
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)498 status_t BnGraphicBufferProducer::onTransact(
499 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
500 {
501 switch(code) {
502 case REQUEST_BUFFER: {
503 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
504 int bufferIdx = data.readInt32();
505 sp<GraphicBuffer> buffer;
506 int result = requestBuffer(bufferIdx, &buffer);
507 reply->writeInt32(buffer != 0);
508 if (buffer != 0) {
509 reply->write(*buffer);
510 }
511 reply->writeInt32(result);
512 return NO_ERROR;
513 }
514 case SET_MAX_DEQUEUED_BUFFER_COUNT: {
515 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
516 int maxDequeuedBuffers = data.readInt32();
517 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers);
518 reply->writeInt32(result);
519 return NO_ERROR;
520 }
521 case SET_ASYNC_MODE: {
522 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
523 bool async = data.readInt32();
524 int result = setAsyncMode(async);
525 reply->writeInt32(result);
526 return NO_ERROR;
527 }
528 case DEQUEUE_BUFFER: {
529 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
530 uint32_t width = data.readUint32();
531 uint32_t height = data.readUint32();
532 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
533 uint32_t usage = data.readUint32();
534 int buf = 0;
535 sp<Fence> fence;
536 int result = dequeueBuffer(&buf, &fence, width, height, format,
537 usage);
538 reply->writeInt32(buf);
539 reply->writeInt32(fence != NULL);
540 if (fence != NULL) {
541 reply->write(*fence);
542 }
543 reply->writeInt32(result);
544 return NO_ERROR;
545 }
546 case DETACH_BUFFER: {
547 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
548 int slot = data.readInt32();
549 int result = detachBuffer(slot);
550 reply->writeInt32(result);
551 return NO_ERROR;
552 }
553 case DETACH_NEXT_BUFFER: {
554 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
555 sp<GraphicBuffer> buffer;
556 sp<Fence> fence;
557 int32_t result = detachNextBuffer(&buffer, &fence);
558 reply->writeInt32(result);
559 if (result == NO_ERROR) {
560 reply->writeInt32(buffer != NULL);
561 if (buffer != NULL) {
562 reply->write(*buffer);
563 }
564 reply->writeInt32(fence != NULL);
565 if (fence != NULL) {
566 reply->write(*fence);
567 }
568 }
569 return NO_ERROR;
570 }
571 case ATTACH_BUFFER: {
572 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
573 sp<GraphicBuffer> buffer = new GraphicBuffer();
574 status_t result = data.read(*buffer.get());
575 int slot = 0;
576 if (result == NO_ERROR) {
577 result = attachBuffer(&slot, buffer);
578 }
579 reply->writeInt32(slot);
580 reply->writeInt32(result);
581 return NO_ERROR;
582 }
583 case QUEUE_BUFFER: {
584 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
585 int buf = data.readInt32();
586 QueueBufferInput input(data);
587 QueueBufferOutput* const output =
588 reinterpret_cast<QueueBufferOutput *>(
589 reply->writeInplace(sizeof(QueueBufferOutput)));
590 memset(output, 0, sizeof(QueueBufferOutput));
591 status_t result = queueBuffer(buf, input, output);
592 reply->writeInt32(result);
593 return NO_ERROR;
594 }
595 case CANCEL_BUFFER: {
596 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
597 int buf = data.readInt32();
598 sp<Fence> fence = new Fence();
599 status_t result = data.read(*fence.get());
600 if (result == NO_ERROR) {
601 result = cancelBuffer(buf, fence);
602 }
603 reply->writeInt32(result);
604 return NO_ERROR;
605 }
606 case QUERY: {
607 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
608 int value = 0;
609 int what = data.readInt32();
610 int res = query(what, &value);
611 reply->writeInt32(value);
612 reply->writeInt32(res);
613 return NO_ERROR;
614 }
615 case CONNECT: {
616 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
617 sp<IProducerListener> listener;
618 if (data.readInt32() == 1) {
619 listener = IProducerListener::asInterface(data.readStrongBinder());
620 }
621 int api = data.readInt32();
622 bool producerControlledByApp = data.readInt32();
623 QueueBufferOutput* const output =
624 reinterpret_cast<QueueBufferOutput *>(
625 reply->writeInplace(sizeof(QueueBufferOutput)));
626 memset(output, 0, sizeof(QueueBufferOutput));
627 status_t res = connect(listener, api, producerControlledByApp, output);
628 reply->writeInt32(res);
629 return NO_ERROR;
630 }
631 case DISCONNECT: {
632 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
633 int api = data.readInt32();
634 DisconnectMode mode = static_cast<DisconnectMode>(data.readInt32());
635 status_t res = disconnect(api, mode);
636 reply->writeInt32(res);
637 return NO_ERROR;
638 }
639 case SET_SIDEBAND_STREAM: {
640 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
641 sp<NativeHandle> stream;
642 if (data.readInt32()) {
643 stream = NativeHandle::create(data.readNativeHandle(), true);
644 }
645 status_t result = setSidebandStream(stream);
646 reply->writeInt32(result);
647 return NO_ERROR;
648 }
649 case ALLOCATE_BUFFERS: {
650 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
651 uint32_t width = data.readUint32();
652 uint32_t height = data.readUint32();
653 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
654 uint32_t usage = data.readUint32();
655 allocateBuffers(width, height, format, usage);
656 return NO_ERROR;
657 }
658 case ALLOW_ALLOCATION: {
659 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
660 bool allow = static_cast<bool>(data.readInt32());
661 status_t result = allowAllocation(allow);
662 reply->writeInt32(result);
663 return NO_ERROR;
664 }
665 case SET_GENERATION_NUMBER: {
666 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
667 uint32_t generationNumber = data.readUint32();
668 status_t result = setGenerationNumber(generationNumber);
669 reply->writeInt32(result);
670 return NO_ERROR;
671 }
672 case GET_CONSUMER_NAME: {
673 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
674 reply->writeString8(getConsumerName());
675 return NO_ERROR;
676 }
677 case SET_SHARED_BUFFER_MODE: {
678 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
679 bool sharedBufferMode = data.readInt32();
680 status_t result = setSharedBufferMode(sharedBufferMode);
681 reply->writeInt32(result);
682 return NO_ERROR;
683 }
684 case SET_AUTO_REFRESH: {
685 CHECK_INTERFACE(IGraphicBuffer, data, reply);
686 bool autoRefresh = data.readInt32();
687 status_t result = setAutoRefresh(autoRefresh);
688 reply->writeInt32(result);
689 return NO_ERROR;
690 }
691 case SET_DEQUEUE_TIMEOUT: {
692 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
693 nsecs_t timeout = data.readInt64();
694 status_t result = setDequeueTimeout(timeout);
695 reply->writeInt32(result);
696 return NO_ERROR;
697 }
698 case GET_LAST_QUEUED_BUFFER: {
699 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
700 sp<GraphicBuffer> buffer(nullptr);
701 sp<Fence> fence(Fence::NO_FENCE);
702 float transform[16] = {};
703 status_t result = getLastQueuedBuffer(&buffer, &fence, transform);
704 reply->writeInt32(result);
705 if (result != NO_ERROR) {
706 return result;
707 }
708 if (!buffer.get()) {
709 reply->writeBool(false);
710 } else {
711 reply->writeBool(true);
712 result = reply->write(*buffer);
713 if (result == NO_ERROR) {
714 reply->write(transform, sizeof(float) * 16);
715 }
716 }
717 if (result != NO_ERROR) {
718 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result);
719 return result;
720 }
721 result = reply->write(*fence);
722 if (result != NO_ERROR) {
723 ALOGE("getLastQueuedBuffer failed to write fence: %d", result);
724 return result;
725 }
726 return NO_ERROR;
727 }
728 case GET_FRAME_TIMESTAMPS: {
729 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
730 uint64_t frameNumber = 0;
731 status_t result = data.readUint64(&frameNumber);
732 if (result != NO_ERROR) {
733 ALOGE("onTransact failed to read: %d", result);
734 return result;
735 }
736 FrameTimestamps timestamps;
737 bool found = getFrameTimestamps(frameNumber, ×tamps);
738 result = reply->writeBool(found);
739 if (result != NO_ERROR) {
740 ALOGE("onTransact failed to write: %d", result);
741 return result;
742 }
743 if (found) {
744 result = reply->write(timestamps);
745 if (result != NO_ERROR) {
746 ALOGE("onTransact failed to write timestamps: %d", result);
747 return result;
748 }
749 }
750 return NO_ERROR;
751 }
752 case GET_UNIQUE_ID: {
753 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
754 uint64_t outId = 0;
755 status_t actualResult = getUniqueId(&outId);
756 status_t result = reply->writeInt32(actualResult);
757 if (result != NO_ERROR) {
758 return result;
759 }
760 result = reply->writeUint64(outId);
761 if (result != NO_ERROR) {
762 return result;
763 }
764 return NO_ERROR;
765 }
766 }
767 return BBinder::onTransact(code, data, reply, flags);
768 }
769
770 // ----------------------------------------------------------------------------
771
QueueBufferInput(const Parcel & parcel)772 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
773 parcel.read(*this);
774 }
775
getFlattenedSize() const776 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
777 return sizeof(timestamp)
778 + sizeof(isAutoTimestamp)
779 + sizeof(dataSpace)
780 + sizeof(crop)
781 + sizeof(scalingMode)
782 + sizeof(transform)
783 + sizeof(stickyTransform)
784 + fence->getFlattenedSize()
785 + surfaceDamage.getFlattenedSize();
786 }
787
getFdCount() const788 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
789 return fence->getFdCount();
790 }
791
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const792 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
793 void*& buffer, size_t& size, int*& fds, size_t& count) const
794 {
795 if (size < getFlattenedSize()) {
796 return NO_MEMORY;
797 }
798 FlattenableUtils::write(buffer, size, timestamp);
799 FlattenableUtils::write(buffer, size, isAutoTimestamp);
800 FlattenableUtils::write(buffer, size, dataSpace);
801 FlattenableUtils::write(buffer, size, crop);
802 FlattenableUtils::write(buffer, size, scalingMode);
803 FlattenableUtils::write(buffer, size, transform);
804 FlattenableUtils::write(buffer, size, stickyTransform);
805 status_t result = fence->flatten(buffer, size, fds, count);
806 if (result != NO_ERROR) {
807 return result;
808 }
809 return surfaceDamage.flatten(buffer, size);
810 }
811
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)812 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
813 void const*& buffer, size_t& size, int const*& fds, size_t& count)
814 {
815 size_t minNeeded =
816 sizeof(timestamp)
817 + sizeof(isAutoTimestamp)
818 + sizeof(dataSpace)
819 + sizeof(crop)
820 + sizeof(scalingMode)
821 + sizeof(transform)
822 + sizeof(stickyTransform);
823
824 if (size < minNeeded) {
825 return NO_MEMORY;
826 }
827
828 FlattenableUtils::read(buffer, size, timestamp);
829 FlattenableUtils::read(buffer, size, isAutoTimestamp);
830 FlattenableUtils::read(buffer, size, dataSpace);
831 FlattenableUtils::read(buffer, size, crop);
832 FlattenableUtils::read(buffer, size, scalingMode);
833 FlattenableUtils::read(buffer, size, transform);
834 FlattenableUtils::read(buffer, size, stickyTransform);
835
836 fence = new Fence();
837 status_t result = fence->unflatten(buffer, size, fds, count);
838 if (result != NO_ERROR) {
839 return result;
840 }
841 return surfaceDamage.unflatten(buffer, size);
842 }
843
844 }; // namespace android
845