OSDN Git Service

SurfaceFlinger: Add NULL check for buffer handling
[android-x86/frameworks-native.git] / libs / gui / IGraphicBufferProducer.cpp
index c949817..6b38811 100644 (file)
@@ -37,12 +37,10 @@ enum {
     QUEUE_BUFFER,
     CANCEL_BUFFER,
     QUERY,
-    SET_SYNCHRONOUS_MODE,
     CONNECT,
     DISCONNECT,
 };
 
-
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
 {
 public:
@@ -81,10 +79,11 @@ public:
         return result;
     }
 
-    virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence,
+    virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
             uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32(async);
         data.writeInt32(w);
         data.writeInt32(h);
         data.writeInt32(format);
@@ -94,11 +93,10 @@ public:
             return result;
         }
         *buf = reply.readInt32();
-        fence.clear();
-        bool hasFence = reply.readInt32();
-        if (hasFence) {
-            fence = new Fence();
-            reply.read(*fence.get());
+        bool nonNull = reply.readInt32();
+        if (nonNull) {
+            *fence = new Fence();
+            reply.read(**fence);
         }
         result = reply.readInt32();
         return result;
@@ -114,20 +112,21 @@ public:
         if (result != NO_ERROR) {
             return result;
         }
-        memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
+        const void *out_data =reply.readInplace(sizeof(*output));
+        if(out_data != NULL) {
+            memcpy(output, out_data, sizeof(*output));
+        } else {
+            return BAD_VALUE;
+        }
         result = reply.readInt32();
         return result;
     }
 
-    virtual void cancelBuffer(int buf, sp<Fence> fence) {
+    virtual void cancelBuffer(int buf, const sp<Fence>& fence) {
         Parcel data, reply;
-        bool hasFence = fence.get() && fence->isValid();
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
         data.writeInt32(buf);
-        data.writeInt32(hasFence);
-        if (hasFence) {
-            data.write(*fence.get());
-        }
+        data.write(*fence.get());
         remote()->transact(CANCEL_BUFFER, data, &reply);
     }
 
@@ -144,27 +143,23 @@ public:
         return result;
     }
 
-    virtual status_t setSynchronousMode(bool enabled) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
-        data.writeInt32(enabled);
-        status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
-        if (result != NO_ERROR) {
-            return result;
-        }
-        result = reply.readInt32();
-        return result;
-    }
-
-    virtual status_t connect(int api, QueueBufferOutput* output) {
+    virtual status_t connect(const sp<IBinder>& token,
+            int api, bool producerControlledByApp, QueueBufferOutput* output) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
         data.writeInt32(api);
+        data.writeInt32(producerControlledByApp);
         status_t result = remote()->transact(CONNECT, data, &reply);
         if (result != NO_ERROR) {
             return result;
         }
-        memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
+        const void *out_data =reply.readInplace(sizeof(*output));
+        if(out_data != NULL) {
+            memcpy(output, out_data, sizeof(*output));
+        } else {
+            return BAD_VALUE;
+        }
         result = reply.readInt32();
         return result;
     }
@@ -211,18 +206,18 @@ status_t BnGraphicBufferProducer::onTransact(
         } break;
         case DEQUEUE_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            bool async      = data.readInt32();
             uint32_t w      = data.readInt32();
             uint32_t h      = data.readInt32();
             uint32_t format = data.readInt32();
             uint32_t usage  = data.readInt32();
             int buf;
             sp<Fence> fence;
-            int result = dequeueBuffer(&buf, fence, w, h, format, usage);
-            bool hasFence = fence.get() && fence->isValid();
+            int result = dequeueBuffer(&buf, &fence, async, w, h, format, usage);
             reply->writeInt32(buf);
-            reply->writeInt32(hasFence);
-            if (hasFence) {
-                reply->write(*fence.get());
+            reply->writeInt32(fence != NULL);
+            if (fence != NULL) {
+                reply->write(*fence);
             }
             reply->writeInt32(result);
             return NO_ERROR;
@@ -241,12 +236,8 @@ status_t BnGraphicBufferProducer::onTransact(
         case CANCEL_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             int buf = data.readInt32();
-            sp<Fence> fence;
-            bool hasFence = data.readInt32();
-            if (hasFence) {
-                fence = new Fence();
-                data.read(*fence.get());
-            }
+            sp<Fence> fence = new Fence();
+            data.read(*fence.get());
             cancelBuffer(buf, fence);
             return NO_ERROR;
         } break;
@@ -259,20 +250,15 @@ status_t BnGraphicBufferProducer::onTransact(
             reply->writeInt32(res);
             return NO_ERROR;
         } break;
-        case SET_SYNCHRONOUS_MODE: {
-            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
-            bool enabled = data.readInt32();
-            status_t res = setSynchronousMode(enabled);
-            reply->writeInt32(res);
-            return NO_ERROR;
-        } break;
         case CONNECT: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
             int api = data.readInt32();
+            bool producerControlledByApp = data.readInt32();
             QueueBufferOutput* const output =
                     reinterpret_cast<QueueBufferOutput *>(
                             reply->writeInplace(sizeof(QueueBufferOutput)));
-            status_t res = connect(api, output);
+            status_t res = connect(token, api, producerControlledByApp, output);
             reply->writeInt32(res);
             return NO_ERROR;
         } break;
@@ -289,62 +275,63 @@ status_t BnGraphicBufferProducer::onTransact(
 
 // ----------------------------------------------------------------------------
 
-static bool isValid(const sp<Fence>& fence) {
-    return fence.get() && fence->isValid();
-}
-
 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
     parcel.read(*this);
 }
 
-size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const
-{
+size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
     return sizeof(timestamp)
+         + sizeof(isAutoTimestamp)
          + sizeof(crop)
          + sizeof(scalingMode)
          + sizeof(transform)
-         + sizeof(bool)
-         + (isValid(fence) ? fence->getFlattenedSize() : 0);
+         + sizeof(async)
+         + fence->getFlattenedSize();
 }
 
-size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const
-{
-    return isValid(fence) ? fence->getFdCount() : 0;
+size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
+    return fence->getFdCount();
 }
 
-status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size,
-        int fds[], size_t count) const
+status_t IGraphicBufferProducer::QueueBufferInput::flatten(
+        void*& buffer, size_t& size, int*& fds, size_t& count) const
 {
-    status_t err = NO_ERROR;
-    bool haveFence = isValid(fence);
-    char* p = (char*)buffer;
-    memcpy(p, &timestamp,   sizeof(timestamp));   p += sizeof(timestamp);
-    memcpy(p, &crop,        sizeof(crop));        p += sizeof(crop);
-    memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode);
-    memcpy(p, &transform,   sizeof(transform));   p += sizeof(transform);
-    memcpy(p, &haveFence,   sizeof(haveFence));   p += sizeof(haveFence);
-    if (haveFence) {
-        err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
+    if (size < getFlattenedSize()) {
+        return NO_MEMORY;
     }
-    return err;
+    FlattenableUtils::write(buffer, size, timestamp);
+    FlattenableUtils::write(buffer, size, isAutoTimestamp);
+    FlattenableUtils::write(buffer, size, crop);
+    FlattenableUtils::write(buffer, size, scalingMode);
+    FlattenableUtils::write(buffer, size, transform);
+    FlattenableUtils::write(buffer, size, async);
+    return fence->flatten(buffer, size, fds, count);
 }
 
-status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer,
-        size_t size, int fds[], size_t count)
+status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
+        void const*& buffer, size_t& size, int const*& fds, size_t& count)
 {
-    status_t err = NO_ERROR;
-    bool haveFence;
-    const char* p = (const char*)buffer;
-    memcpy(&timestamp,   p, sizeof(timestamp));   p += sizeof(timestamp);
-    memcpy(&crop,        p, sizeof(crop));        p += sizeof(crop);
-    memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode);
-    memcpy(&transform,   p, sizeof(transform));   p += sizeof(transform);
-    memcpy(&haveFence,   p, sizeof(haveFence));   p += sizeof(haveFence);
-    if (haveFence) {
-        fence = new Fence();
-        err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count);
+    size_t minNeeded =
+              sizeof(timestamp)
+            + sizeof(isAutoTimestamp)
+            + sizeof(crop)
+            + sizeof(scalingMode)
+            + sizeof(transform)
+            + sizeof(async);
+
+    if (size < minNeeded) {
+        return NO_MEMORY;
     }
-    return err;
+
+    FlattenableUtils::read(buffer, size, timestamp);
+    FlattenableUtils::read(buffer, size, isAutoTimestamp);
+    FlattenableUtils::read(buffer, size, crop);
+    FlattenableUtils::read(buffer, size, scalingMode);
+    FlattenableUtils::read(buffer, size, transform);
+    FlattenableUtils::read(buffer, size, async);
+
+    fence = new Fence();
+    return fence->unflatten(buffer, size, fds, count);
 }
 
 }; // namespace android