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