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