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