OSDN Git Service

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