OSDN Git Service

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