• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamps);
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