Added libgui_bufferQueue_fuzzer

Test: ./libgui_bufferQueue_fuzzer
Bug: 202910330

Change-Id: I2626dc65a5209c6053f115f300c6fc22671ad1c2
diff --git a/libs/gui/fuzzer/Android.bp b/libs/gui/fuzzer/Android.bp
index f9e01de..071950b 100644
--- a/libs/gui/fuzzer/Android.bp
+++ b/libs/gui/fuzzer/Android.bp
@@ -105,3 +105,13 @@
         "libgui_fuzzer_defaults",
     ],
 }
+
+cc_fuzz {
+    name: "libgui_bufferQueue_fuzzer",
+    srcs: [
+        "libgui_bufferQueue_fuzzer.cpp",
+    ],
+    defaults: [
+        "libgui_fuzzer_defaults",
+    ],
+}
diff --git a/libs/gui/fuzzer/README.md b/libs/gui/fuzzer/README.md
index 24edd57..d6bc52e 100644
--- a/libs/gui/fuzzer/README.md
+++ b/libs/gui/fuzzer/README.md
@@ -4,6 +4,7 @@
 + [libgui_surfaceComposer_fuzzer](#SurfaceComposer)
 + [libgui_surfaceComposerClient_fuzzer](#SurfaceComposerClient)
 + [libgui_parcelable_fuzzer](#Libgui_Parcelable)
++ [libgui_bufferQueue_fuzzer](#BufferQueue)
 
 # <a name="libgui_surfaceComposer_fuzzer"></a> Fuzzer for SurfaceComposer
 
@@ -122,3 +123,49 @@
   $ adb sync data
   $ adb shell /data/fuzz/arm64/libgui_fuzzer/libgui_fuzzer
 ```
+
+# <a name="libgui_bufferQueue_fuzzer"></a> Fuzzer for BufferQueue
+
+BufferQueue supports the following parameters:
+1. SurfaceWidth (parameter name:`width`)
+2. SurfaceHeight (parameter name:`height`)
+3. TransactionStateFlags (parameter name:`flags`)
+4. TransformHint (parameter name:`outTransformHint`)
+5. SurfacePixelFormat (parameter name:`format`)
+6. LayerId (parameter name:`layerId`)
+7. BufferId (parameter name:`bufferId`)
+8. FrameNumber (parameter name:`frameNumber`)
+9. FrameRate (parameter name:`frameRate`)
+10. Compatability (parameter name:`compatability`)
+11. LatchTime (parameter name:`latchTime`)
+12. AcquireTime (parameter name:`acquireTime`)
+13. RefreshTime (parameter name:`refreshTime`)
+14. DequeueTime (parameter name:`dequeueTime`)
+15. Slot (parameter name:`slot`)
+16. MaxBuffers (parameter name:`maxBuffers`)
+17. GenerationNumber (parameter name:`generationNumber`)
+18. Api (parameter name:`api`)
+19. Usage (parameter name:`usage`)
+20. MaxFrameNumber (parameter name:`maxFrameNumber`)
+21. BufferCount (parameter name:`bufferCount`)
+22. MaxAcquredBufferCount (parameter name:`maxAcquredBufferCount`)
+23. Status (parameter name:`status`)
+24. ApiConnection (parameter name:`apiConnection`)
+25. Dataspace (parameter name:`dataspace`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`status`| 0.`OK`, 1.`NO_MEMORY`, 2.`NO_INIT`, 3.`BAD_VALUE`, 4.`DEAD_OBJECT`, 5.`INVALID_OPERATION`, 6.`TIMED_OUT`, 7.`WOULD_BLOCK`, 8.`UNKNOWN_ERROR`, 9.`ALREADY_EXISTS`, |Value obtained from FuzzedDataProvider|
+|`apiConnection`| 0.`BufferQueueCore::CURRENTLY_CONNECTED_API`, 1.`BufferQueueCore::NO_CONNECTED_API`, 2.`NATIVE_WINDOW_API_EGL`, 3.`NATIVE_WINDOW_API_CPU`, 4.`NATIVE_WINDOW_API_MEDIA`, 5.`NATIVE_WINDOW_API_CAMERA`, |Value obtained from FuzzedDataProvider|
+|`dataspace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) libgui_bufferQueue_fuzzer
+```
+2. To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/libgui_bufferQueue_fuzzer/libgui_bufferQueue_fuzzer
+```
diff --git a/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp b/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp
new file mode 100644
index 0000000..c97770b
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gui/BufferQueueConsumer.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <system/window.h>
+
+#include <libgui_fuzzer_utils.h>
+
+using namespace android;
+using namespace hardware::graphics::bufferqueue;
+using namespace V1_0::utils;
+using namespace V2_0::utils;
+
+constexpr int32_t kMaxBytes = 256;
+
+constexpr int32_t kError[] = {
+        OK,        NO_MEMORY,   NO_INIT,       BAD_VALUE,      DEAD_OBJECT, INVALID_OPERATION,
+        TIMED_OUT, WOULD_BLOCK, UNKNOWN_ERROR, ALREADY_EXISTS,
+};
+
+constexpr int32_t kAPIConnection[] = {
+        BufferQueueCore::CURRENTLY_CONNECTED_API,
+        BufferQueueCore::NO_CONNECTED_API,
+        NATIVE_WINDOW_API_EGL,
+        NATIVE_WINDOW_API_CPU,
+        NATIVE_WINDOW_API_MEDIA,
+        NATIVE_WINDOW_API_CAMERA,
+};
+
+class BufferQueueFuzzer {
+public:
+    BufferQueueFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+private:
+    void invokeTypes();
+    void invokeH2BGraphicBufferV1();
+    void invokeH2BGraphicBufferV2();
+    void invokeBufferQueueConsumer();
+    void invokeBufferQueueProducer();
+    void invokeBlastBufferQueue();
+    void invokeQuery(sp<BufferQueueProducer>);
+    void invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer>);
+    void invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer>);
+    void invokeAcquireBuffer(sp<BufferQueueConsumer>);
+    void invokeOccupancyTracker(sp<BufferQueueConsumer>);
+    sp<SurfaceControl> makeSurfaceControl();
+    sp<BLASTBufferQueue> makeBLASTBufferQueue(sp<SurfaceControl>);
+
+    FuzzedDataProvider mFdp;
+};
+
+class ManageResourceHandle {
+public:
+    ManageResourceHandle(FuzzedDataProvider* fdp) {
+        mNativeHandle = native_handle_create(0 /*numFds*/, 1 /*numInts*/);
+        mShouldOwn = fdp->ConsumeBool();
+        mStream = NativeHandle::create(mNativeHandle, mShouldOwn);
+    }
+    ~ManageResourceHandle() {
+        if (!mShouldOwn) {
+            native_handle_close(mNativeHandle);
+            native_handle_delete(mNativeHandle);
+        }
+    }
+    sp<NativeHandle> getStream() { return mStream; }
+
+private:
+    bool mShouldOwn;
+    sp<NativeHandle> mStream;
+    native_handle_t* mNativeHandle;
+};
+
+sp<SurfaceControl> BufferQueueFuzzer::makeSurfaceControl() {
+    sp<IBinder> handle;
+    const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
+    sp<BnGraphicBufferProducer> producer;
+    return sp<SurfaceControl>::make(client, handle, mFdp.ConsumeIntegral<int32_t>(),
+                                    mFdp.ConsumeIntegral<uint32_t>(),
+                                    mFdp.ConsumeIntegral<uint32_t>(),
+                                    mFdp.ConsumeIntegral<int32_t>(),
+                                    mFdp.ConsumeIntegral<uint32_t>(),
+                                    mFdp.ConsumeIntegral<uint32_t>());
+}
+
+sp<BLASTBufferQueue> BufferQueueFuzzer::makeBLASTBufferQueue(sp<SurfaceControl> surface) {
+    return sp<BLASTBufferQueue>::make(mFdp.ConsumeRandomLengthString(kMaxBytes), surface,
+                                      mFdp.ConsumeIntegral<uint32_t>(),
+                                      mFdp.ConsumeIntegral<uint32_t>(),
+                                      mFdp.ConsumeIntegral<int32_t>());
+}
+
+void BufferQueueFuzzer::invokeBlastBufferQueue() {
+    sp<SurfaceControl> surface = makeSurfaceControl();
+    sp<BLASTBufferQueue> queue = makeBLASTBufferQueue(surface);
+
+    BufferItem item;
+    queue->onFrameAvailable(item);
+    queue->onFrameReplaced(item);
+    uint64_t bufferId = mFdp.ConsumeIntegral<uint64_t>();
+    queue->onFrameDequeued(bufferId);
+    queue->onFrameCancelled(bufferId);
+
+    SurfaceComposerClient::Transaction next;
+    uint64_t frameNumber = mFdp.ConsumeIntegral<uint64_t>();
+    queue->mergeWithNextTransaction(&next, frameNumber);
+    queue->applyPendingTransactions(frameNumber);
+
+    queue->update(surface, mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+                  mFdp.ConsumeIntegral<int32_t>());
+    queue->setFrameRate(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeIntegral<int8_t>(),
+                        mFdp.ConsumeBool() /*shouldBeSeamless*/);
+    FrameTimelineInfo info;
+    queue->setFrameTimelineInfo(info);
+
+    ManageResourceHandle handle(&mFdp);
+    queue->setSidebandStream(handle.getStream());
+
+    queue->getLastTransformHint();
+    queue->getLastAcquiredFrameNum();
+
+    CompositorTiming compTiming;
+    sp<Fence> previousFence = new Fence(memfd_create("pfd", MFD_ALLOW_SEALING));
+    sp<Fence> gpuFence = new Fence(memfd_create("gfd", MFD_ALLOW_SEALING));
+    FrameEventHistoryStats frameStats(frameNumber, gpuFence, compTiming,
+                                      mFdp.ConsumeIntegral<int64_t>(),
+                                      mFdp.ConsumeIntegral<int64_t>());
+    std::vector<SurfaceControlStats> stats;
+    sp<Fence> presentFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
+    SurfaceControlStats controlStats(surface, mFdp.ConsumeIntegral<int64_t>(),
+                                     mFdp.ConsumeIntegral<int64_t>(), presentFence, previousFence,
+                                     mFdp.ConsumeIntegral<uint32_t>(), frameStats);
+    stats.push_back(controlStats);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<BufferQueueProducer> producer) {
+    int32_t value;
+    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer) {
+    int32_t value;
+    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer) {
+    int32_t value;
+    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeBufferQueueProducer() {
+    sp<BufferQueueCore> core(new BufferQueueCore());
+    sp<BufferQueueProducer> producer(new BufferQueueProducer(core));
+    const sp<android::IProducerListener> listener;
+    android::IGraphicBufferProducer::QueueBufferOutput output;
+    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+    sp<GraphicBuffer> buffer;
+    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+    uint32_t maxBuffers = mFdp.ConsumeIntegral<uint32_t>();
+    producer->requestBuffer(slot, &buffer);
+    producer->setMaxDequeuedBufferCount(maxBuffers);
+    producer->setAsyncMode(mFdp.ConsumeBool() /*async*/);
+
+    android::IGraphicBufferProducer::QueueBufferInput input;
+    producer->attachBuffer(&slot, buffer);
+    producer->queueBuffer(slot, input, &output);
+
+    int32_t format = mFdp.ConsumeIntegral<int32_t>();
+    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+    uint64_t outBufferAge;
+    FrameEventHistoryDelta outTimestamps;
+    sp<android::Fence> fence;
+    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+                            &outTimestamps);
+    producer->detachBuffer(slot);
+    producer->detachNextBuffer(&buffer, &fence);
+    producer->cancelBuffer(slot, fence);
+
+    invokeQuery(producer);
+
+    ManageResourceHandle handle(&mFdp);
+    producer->setSidebandStream(handle.getStream());
+
+    producer->allocateBuffers(width, height, format, usage);
+    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+    producer->setLegacyBufferDrop(mFdp.ConsumeBool() /*drop*/);
+    producer->setAutoPrerotation(mFdp.ConsumeBool() /*autoPrerotation*/);
+
+    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+    producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::invokeAcquireBuffer(sp<BufferQueueConsumer> consumer) {
+    BufferItem item;
+    consumer->acquireBuffer(&item, mFdp.ConsumeIntegral<uint32_t>(),
+                            mFdp.ConsumeIntegral<uint64_t>());
+}
+
+void BufferQueueFuzzer::invokeOccupancyTracker(sp<BufferQueueConsumer> consumer) {
+    String8 outResult;
+    String8 prefix((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+    consumer->dumpState(prefix, &outResult);
+
+    std::vector<OccupancyTracker::Segment> outHistory;
+    consumer->getOccupancyHistory(mFdp.ConsumeBool() /*forceFlush*/, &outHistory);
+}
+
+void BufferQueueFuzzer::invokeBufferQueueConsumer() {
+    sp<BufferQueueCore> core(new BufferQueueCore());
+    sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
+    sp<android::IConsumerListener> listener;
+    consumer->consumerConnect(listener, mFdp.ConsumeBool() /*controlledByApp*/);
+    invokeAcquireBuffer(consumer);
+
+    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+    sp<GraphicBuffer> buffer =
+            new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+                              mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+                              mFdp.ConsumeIntegral<uint64_t>());
+    consumer->attachBuffer(&slot, buffer);
+    consumer->detachBuffer(slot);
+
+    consumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(),
+                                   mFdp.ConsumeIntegral<uint32_t>());
+    consumer->setMaxBufferCount(mFdp.ConsumeIntegral<int32_t>());
+    consumer->setMaxAcquiredBufferCount(mFdp.ConsumeIntegral<int32_t>());
+
+    String8 name((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+    consumer->setConsumerName(name);
+    consumer->setDefaultBufferFormat(mFdp.ConsumeIntegral<int32_t>());
+    android_dataspace dataspace =
+            static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
+    consumer->setDefaultBufferDataSpace(dataspace);
+
+    consumer->setTransformHint(mFdp.ConsumeIntegral<uint32_t>());
+    consumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>());
+    consumer->setConsumerIsProtected(mFdp.ConsumeBool() /*isProtected*/);
+    invokeOccupancyTracker(consumer);
+
+    sp<Fence> releaseFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
+    consumer->releaseBuffer(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint64_t>(),
+                            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
+    consumer->consumerDisconnect();
+}
+
+void BufferQueueFuzzer::invokeTypes() {
+    HStatus hStatus;
+    int32_t status = mFdp.PickValueInArray(kError);
+    bool bufferNeedsReallocation = mFdp.ConsumeBool();
+    bool releaseAllBuffers = mFdp.ConsumeBool();
+    b2h(status, &hStatus, &bufferNeedsReallocation, &releaseAllBuffers);
+    h2b(hStatus, &status);
+
+    HConnectionType type;
+    int32_t apiConnection = mFdp.PickValueInArray(kAPIConnection);
+    b2h(apiConnection, &type);
+    h2b(type, &apiConnection);
+}
+
+void BufferQueueFuzzer::invokeH2BGraphicBufferV1() {
+    sp<V1_0::utils::H2BGraphicBufferProducer> producer(
+            new V1_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV1()));
+    const sp<android::IProducerListener> listener;
+    android::IGraphicBufferProducer::QueueBufferOutput output;
+    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+    sp<GraphicBuffer> buffer;
+    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+    producer->requestBuffer(slot, &buffer);
+    producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<int32_t>());
+    producer->setAsyncMode(mFdp.ConsumeBool());
+
+    android::IGraphicBufferProducer::QueueBufferInput input;
+    input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
+    producer->attachBuffer(&slot, buffer);
+    producer->queueBuffer(slot, input, &output);
+
+    int32_t format = mFdp.ConsumeIntegral<int32_t>();
+    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+    uint64_t outBufferAge;
+    FrameEventHistoryDelta outTimestamps;
+    sp<android::Fence> fence;
+    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+                            &outTimestamps);
+    producer->detachBuffer(slot);
+    producer->cancelBuffer(slot, fence);
+
+    invokeQuery(producer);
+
+    ManageResourceHandle handle(&mFdp);
+    producer->setSidebandStream(handle.getStream());
+
+    producer->allocateBuffers(width, height, format, usage);
+    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+
+    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+    producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::invokeH2BGraphicBufferV2() {
+    sp<V2_0::utils::H2BGraphicBufferProducer> producer(
+            new V2_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV2()));
+    const sp<android::IProducerListener> listener;
+    android::IGraphicBufferProducer::QueueBufferOutput output;
+    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+    sp<GraphicBuffer> buffer;
+    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+    producer->requestBuffer(slot, &buffer);
+    producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<uint32_t>());
+    producer->setAsyncMode(mFdp.ConsumeBool());
+
+    android::IGraphicBufferProducer::QueueBufferInput input;
+    input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
+    producer->attachBuffer(&slot, buffer);
+    producer->queueBuffer(slot, input, &output);
+
+    int32_t format = mFdp.ConsumeIntegral<int32_t>();
+    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+    uint64_t outBufferAge;
+    FrameEventHistoryDelta outTimestamps;
+    sp<android::Fence> fence;
+    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+                            &outTimestamps);
+    producer->detachBuffer(slot);
+    producer->cancelBuffer(slot, fence);
+
+    invokeQuery(producer);
+
+    ManageResourceHandle handle(&mFdp);
+    producer->setSidebandStream(handle.getStream());
+
+    producer->allocateBuffers(width, height, format, usage);
+    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+
+    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+    producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::process() {
+    invokeBlastBufferQueue();
+    invokeH2BGraphicBufferV1();
+    invokeH2BGraphicBufferV2();
+    invokeTypes();
+    invokeBufferQueueConsumer();
+    invokeBufferQueueProducer();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    BufferQueueFuzzer bufferQueueFuzzer(data, size);
+    bufferQueueFuzzer.process();
+    return 0;
+}