diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp
index 7eebd9b..0ead163 100644
--- a/services/surfaceflinger/fuzzer/Android.bp
+++ b/services/surfaceflinger/fuzzer/Android.bp
@@ -78,3 +78,17 @@
         "surfaceflinger_fuzzer.cpp",
     ],
 }
+
+cc_fuzz {
+    name: "surfaceflinger_displayhardware_fuzzer",
+    defaults: [
+        "surfaceflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "surfaceflinger_displayhardware_fuzzer.cpp",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer@2.4-command-buffer",
+        "android.hardware.graphics.composer@2.4-hal",
+    ],
+}
diff --git a/services/surfaceflinger/fuzzer/README.md b/services/surfaceflinger/fuzzer/README.md
index 7b244fc..4ecf770 100644
--- a/services/surfaceflinger/fuzzer/README.md
+++ b/services/surfaceflinger/fuzzer/README.md
@@ -1,6 +1,7 @@
 # Fuzzers for SurfaceFlinger
 ## Table of contents
 + [SurfaceFlinger](#SurfaceFlinger)
++ [DisplayHardware](#DisplayHardware)
 
 # <a name="SurfaceFlinger"></a> Fuzzer for SurfaceFlinger
 
@@ -22,3 +23,31 @@
   $ adb sync data
   $ adb shell /data/fuzz/arm64/surfaceflinger_fuzzer/surfaceflinger_fuzzer
 ```
+
+# <a name="DisplayHardware"></a> Fuzzer for DisplayHardware
+
+DisplayHardware supports the following parameters:
+1. Hal Capability (parameter name: `hasCapability`)
+2. Hal BlendMode (parameter name: `setBlendMode`)
+3. Hal Composition (parameter name: `setCompositionType`)
+4. Hal Display Capability (parameter name: `hasDisplayCapability`)
+5. Composition Types (parameter name: `prepareFrame`)
+6. Color Modes (parameter name: `setActiveColorMode`)
+7. Render Intents (parameter name: `setActiveColorMode`)
+8. Power Modes (parameter name: `setPowerMode`)
+9. Content Types (parameter name: `setContentType`)
+10. Data Space (parameter name: `setDataspace`)
+11. Transforms (parameter name: `setLayerTransform`)
+
+You can find the possible values in the fuzzer's source code.
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) surfaceflinger_displayhardware_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/surfaceflinger_displayhardware_fuzzer/surfaceflinger_displayhardware_fuzzer
+```
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
new file mode 100644
index 0000000..816d2f1
--- /dev/null
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
@@ -0,0 +1,657 @@
+/*
+ * Copyright 2021 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 <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <compositionengine/impl/OutputCompositionState.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gui/BLASTBufferQueue.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/SurfaceComposerClient.h>
+#include <hidl/ServiceManagement.h>
+#include <hwbinder/ProcessState.h>
+#include <ui/DisplayIdentification.h>
+
+#include "DisplayHardware/AidlComposerHal.h"
+#include "DisplayHardware/DisplayMode.h"
+#include "DisplayHardware/FramebufferSurface.h"
+#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/PowerAdvisor.h"
+#include "DisplayHardware/VirtualDisplaySurface.h"
+#include "SurfaceFlinger.h"
+#include "surfaceflinger_displayhardware_fuzzer_utils.h"
+
+#include <FuzzableDataspaces.h>
+
+namespace android::fuzz {
+
+using namespace android::hardware::graphics::common;
+using namespace android::hardware::graphics::composer;
+namespace hal = android::hardware::graphics::composer::hal;
+using Config = hal::V2_1::Config;
+using Display = hal::V2_1::Display;
+using RenderIntent = V1_1::RenderIntent;
+using IComposerClient = hal::V2_4::IComposerClient;
+using VsyncPeriodChangeTimeline = hal::V2_4::VsyncPeriodChangeTimeline;
+using PerFrameMetadata = IComposerClient::PerFrameMetadata;
+using PerFrameMetadataBlob = IComposerClient::PerFrameMetadataBlob;
+using Vsync = IComposerClient::Vsync;
+
+static constexpr hal::Transform kTransforms[] = {hal::Transform::FLIP_H, hal::Transform::FLIP_V,
+                                                 hal::Transform::ROT_90, hal::Transform::ROT_180,
+                                                 hal::Transform::ROT_270};
+
+static constexpr hal::Capability kCapability[] = {hal::Capability::INVALID,
+                                                  hal::Capability::SIDEBAND_STREAM,
+                                                  hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
+                                                  hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE};
+
+static constexpr hal::BlendMode kBlendModes[] = {hal::BlendMode::INVALID, hal::BlendMode::NONE,
+                                                 hal::BlendMode::PREMULTIPLIED,
+                                                 hal::BlendMode::COVERAGE};
+
+static constexpr Composition kCompositions[] = {Composition::INVALID, Composition::CLIENT,
+                                                Composition::DEVICE,  Composition::SOLID_COLOR,
+                                                Composition::CURSOR,  Composition::SIDEBAND};
+
+static constexpr DisplayCapability kDisplayCapability[] =
+        {DisplayCapability::INVALID,
+         DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM,
+         DisplayCapability::DOZE,
+         DisplayCapability::BRIGHTNESS,
+         DisplayCapability::PROTECTED_CONTENTS,
+         DisplayCapability::AUTO_LOW_LATENCY_MODE};
+
+static constexpr VirtualDisplaySurface::CompositionType kCompositionTypes[] =
+        {VirtualDisplaySurface::CompositionType::Unknown,
+         VirtualDisplaySurface::CompositionType::Gpu, VirtualDisplaySurface::CompositionType::Hwc,
+         VirtualDisplaySurface::CompositionType::Mixed};
+
+static constexpr ui::RenderIntent kRenderIntents[] = {ui::RenderIntent::COLORIMETRIC,
+                                                      ui::RenderIntent::ENHANCE,
+                                                      ui::RenderIntent::TONE_MAP_COLORIMETRIC,
+                                                      ui::RenderIntent::TONE_MAP_ENHANCE};
+
+static constexpr hal::PowerMode kPowerModes[] = {hal::PowerMode::OFF, hal::PowerMode::DOZE,
+                                                 hal::PowerMode::DOZE_SUSPEND, hal::PowerMode::ON,
+                                                 hal::PowerMode::ON_SUSPEND};
+
+static constexpr hal::ContentType kContentTypes[] = {hal::ContentType::NONE,
+                                                     hal::ContentType::GRAPHICS,
+                                                     hal::ContentType::PHOTO,
+                                                     hal::ContentType::CINEMA,
+                                                     hal::ContentType::GAME};
+
+const unsigned char kInternalEdid[] =
+        "\x00\xff\xff\xff\xff\xff\xff\x00\x4c\xa3\x42\x31\x00\x00\x00\x00"
+        "\x00\x15\x01\x03\x80\x1a\x10\x78\x0a\xd3\xe5\x95\x5c\x60\x90\x27"
+        "\x19\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+        "\x01\x01\x01\x01\x01\x01\x9e\x1b\x00\xa0\x50\x20\x12\x30\x10\x30"
+        "\x13\x00\x05\xa3\x10\x00\x00\x19\x00\x00\x00\x0f\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x23\x87\x02\x64\x00\x00\x00\x00\xfe\x00\x53"
+        "\x41\x4d\x53\x55\x4e\x47\x0a\x20\x20\x20\x20\x20\x00\x00\x00\xfe"
+        "\x00\x31\x32\x31\x41\x54\x31\x31\x2d\x38\x30\x31\x0a\x20\x00\x45";
+
+static constexpr hal::HWConfigId kActiveConfig = 0;
+
+class DisplayHardwareFuzzer {
+public:
+    DisplayHardwareFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mPhysicalDisplayId = SurfaceComposerClient::getInternalDisplayId().value();
+    };
+    void process();
+
+private:
+    void invokeComposer();
+    void invokeDisplayIdentification();
+    void invokeLayer(HWC2::Layer* layer);
+    void setSidebandStream(HWC2::Layer* layer);
+    void setCursorPosition(HWC2::Layer* layer);
+    void setBuffer(HWC2::Layer* layer);
+    void setSurfaceDamage(HWC2::Layer* layer);
+    void setDisplayFrame(HWC2::Layer* layer);
+    void setVisibleRegion(HWC2::Layer* layer);
+    void setLayerGenericMetadata(HWC2::Layer* layer);
+    void invokeFrameBufferSurface();
+    void invokeVirtualDisplaySurface();
+    void invokeAidlComposer();
+    Display createVirtualDisplay(Hwc2::AidlComposer*);
+    void validateDisplay(Hwc2::AidlComposer*, Display);
+    void presentOrValidateDisplay(Hwc2::AidlComposer*, Display);
+    void setOutputBuffer(Hwc2::AidlComposer*, Display);
+    void setLayerSidebandStream(Hwc2::AidlComposer*, Display, Hwc2::V2_4::hal::Layer);
+    void invokeComposerHal2_2(Hwc2::AidlComposer*, Display, Hwc2::V2_4::hal::Layer);
+    void invokeComposerHal2_3(Hwc2::AidlComposer*, Display, Hwc2::V2_4::hal::Layer);
+    void invokeComposerHal2_4(Hwc2::AidlComposer*, Display, Hwc2::V2_4::hal::Layer);
+    void getDisplayVsyncPeriod();
+    void setActiveModeWithConstraints();
+    void getDisplayIdentificationData();
+    void dumpHwc();
+    void getDisplayedContentSamplingAttributes(HalDisplayId);
+    void getDeviceCompositionChanges(HalDisplayId);
+    void getHdrCapabilities(HalDisplayId);
+    void getDisplayedContentSample(HalDisplayId);
+    void getSupportedContentTypes();
+    ui::Size getFuzzedSize();
+    mat4 getFuzzedMatrix();
+
+    DisplayIdGenerator<HalVirtualDisplayId> mGenerator;
+    FuzzedDataProvider mFdp;
+    PhysicalDisplayId mPhysicalDisplayId;
+    android::impl::HWComposer mHwc{std::make_unique<Hwc2::mock::Composer>()};
+};
+
+void DisplayHardwareFuzzer::validateDisplay(Hwc2::AidlComposer* composer, Display display) {
+    uint32_t outNumTypes, outNumRequests;
+    composer->validateDisplay(display, mFdp.ConsumeIntegral<nsecs_t>(), &outNumTypes,
+                              &outNumRequests);
+}
+
+void DisplayHardwareFuzzer::presentOrValidateDisplay(Hwc2::AidlComposer* composer,
+                                                     Display display) {
+    int32_t outPresentFence;
+    uint32_t outNumTypes, outNumRequests, state;
+    composer->presentOrValidateDisplay(display, mFdp.ConsumeIntegral<nsecs_t>(), &outNumTypes,
+                                       &outNumRequests, &outPresentFence, &state);
+}
+
+void DisplayHardwareFuzzer::setOutputBuffer(Hwc2::AidlComposer* composer, Display display) {
+    const native_handle_t buffer{};
+    composer->setOutputBuffer(display, &buffer, mFdp.ConsumeIntegral<int32_t>() /*releaseFence*/);
+}
+
+void DisplayHardwareFuzzer::setLayerSidebandStream(Hwc2::AidlComposer* composer, Display display,
+                                                   Hwc2::V2_4::hal::Layer outLayer) {
+    const native_handle_t stream{};
+    composer->setLayerSidebandStream(display, outLayer, &stream);
+}
+
+Display DisplayHardwareFuzzer::createVirtualDisplay(Hwc2::AidlComposer* composer) {
+    namespace types = hardware::graphics::common;
+    using types::V1_2::PixelFormat;
+    PixelFormat format{};
+    Display display;
+    composer->createVirtualDisplay(mFdp.ConsumeIntegral<uint32_t>() /*width*/,
+                                   mFdp.ConsumeIntegral<uint32_t>() /*height*/, &format, &display);
+    return display;
+}
+
+void DisplayHardwareFuzzer::getDisplayVsyncPeriod() {
+    nsecs_t outVsyncPeriod;
+    mHwc.getDisplayVsyncPeriod(mPhysicalDisplayId, &outVsyncPeriod);
+}
+
+void DisplayHardwareFuzzer::setActiveModeWithConstraints() {
+    hal::VsyncPeriodChangeTimeline outTimeline;
+    mHwc.setActiveModeWithConstraints(mPhysicalDisplayId, kActiveConfig, {} /*constraints*/,
+                                      &outTimeline);
+}
+
+void DisplayHardwareFuzzer::getDisplayIdentificationData() {
+    uint8_t outPort;
+    DisplayIdentificationData outData;
+    mHwc.getDisplayIdentificationData(kHwDisplayId, &outPort, &outData);
+}
+
+void DisplayHardwareFuzzer::dumpHwc() {
+    std::string string = mFdp.ConsumeRandomLengthString().c_str();
+    mHwc.dump(string);
+}
+
+void DisplayHardwareFuzzer::getDeviceCompositionChanges(HalDisplayId halDisplayID) {
+    std::optional<impl::HWComposer::DeviceRequestedChanges> outChanges;
+    mHwc.getDeviceCompositionChanges(halDisplayID,
+                                     mFdp.ConsumeBool() /*frameUsesClientComposition*/,
+                                     std::chrono::steady_clock::now(), FenceTime::NO_FENCE,
+                                     mFdp.ConsumeIntegral<nsecs_t>(), &outChanges);
+}
+
+void DisplayHardwareFuzzer::getDisplayedContentSamplingAttributes(HalDisplayId halDisplayID) {
+    uint8_t outComponentMask;
+    ui::Dataspace dataSpace;
+    ui::PixelFormat pixelFormat;
+    mHwc.getDisplayedContentSamplingAttributes(halDisplayID, &pixelFormat, &dataSpace,
+                                               &outComponentMask);
+}
+
+void DisplayHardwareFuzzer::getHdrCapabilities(HalDisplayId halDisplayID) {
+    HdrCapabilities outCapabilities;
+    mHwc.getHdrCapabilities(halDisplayID, &outCapabilities);
+}
+
+void DisplayHardwareFuzzer::getDisplayedContentSample(HalDisplayId halDisplayID) {
+    DisplayedFrameStats outStats;
+    mHwc.getDisplayedContentSample(halDisplayID, mFdp.ConsumeIntegral<uint64_t>() /* maxFrames*/,
+                                   mFdp.ConsumeIntegral<uint64_t>() /*timestamps*/, &outStats);
+}
+
+void DisplayHardwareFuzzer::getSupportedContentTypes() {
+    std::vector<hal::ContentType> contentType{};
+    mHwc.getSupportedContentTypes(mPhysicalDisplayId, &contentType);
+}
+
+void DisplayHardwareFuzzer::invokeAidlComposer() {
+    hardware::ProcessState::self()->startThreadPool();
+    ProcessState::self()->startThreadPool();
+
+    if (!Hwc2::AidlComposer::isDeclared("default")) {
+        return;
+    }
+
+    Hwc2::AidlComposer composer("default");
+
+    android::hardware::graphics::composer::hal::TestHWC2ComposerCallback composerCallback{};
+    composer.registerCallback(composerCallback);
+
+    Display display = createVirtualDisplay(&composer);
+
+    composer.acceptDisplayChanges(display);
+
+    Hwc2::V2_4::hal::Layer outLayer;
+    composer.createLayer(display, &outLayer);
+
+    int32_t outPresentFence;
+    composer.presentDisplay(display, &outPresentFence);
+
+    composer.setActiveConfig(display, Config{});
+
+    composer.setClientTarget(display, mFdp.ConsumeIntegral<uint32_t>(), sp<GraphicBuffer>(),
+                             mFdp.ConsumeIntegral<int32_t>(), mFdp.PickValueInArray(kDataspaces),
+                             {});
+
+    composer.setColorMode(display, mFdp.PickValueInArray(kColormodes),
+                          mFdp.PickValueInArray(kRenderIntents));
+
+    setOutputBuffer(&composer, display);
+
+    composer.setPowerMode(display, mFdp.PickValueInArray(kPowerModes));
+    composer.setVsyncEnabled(display, mFdp.ConsumeBool() ? Vsync::ENABLE : Vsync::DISABLE);
+
+    composer.setClientTargetSlotCount(display);
+
+    validateDisplay(&composer, display);
+
+    presentOrValidateDisplay(&composer, display);
+
+    composer.setCursorPosition(display, outLayer, mFdp.ConsumeIntegral<uint8_t>() /*x*/,
+                               mFdp.ConsumeIntegral<uint8_t>() /*y*/);
+
+    composer.setLayerBuffer(display, outLayer, mFdp.ConsumeIntegral<uint32_t>() /*slot*/,
+                            sp<GraphicBuffer>(), mFdp.ConsumeIntegral<int32_t>() /*acquireFence*/);
+
+    composer.setLayerSurfaceDamage(display, outLayer, {} /*damage*/);
+
+    composer.setLayerBlendMode(display, outLayer, mFdp.PickValueInArray(kBlendModes));
+
+    composer.setLayerColor(display, outLayer,
+                           {mFdp.ConsumeFloatingPoint<float>() /*red*/,
+                            mFdp.ConsumeFloatingPoint<float>() /*green*/,
+                            mFdp.ConsumeFloatingPoint<float>() /*blue*/,
+                            mFdp.ConsumeFloatingPoint<float>() /*alpha*/});
+    composer.setLayerCompositionType(display, outLayer, mFdp.PickValueInArray(kCompositions));
+    composer.setLayerDataspace(display, outLayer, mFdp.PickValueInArray(kDataspaces));
+    composer.setLayerDisplayFrame(display, outLayer, {} /*frame*/);
+    composer.setLayerPlaneAlpha(display, outLayer, mFdp.ConsumeFloatingPoint<float>());
+
+    setLayerSidebandStream(&composer, display, outLayer);
+
+    composer.setLayerSourceCrop(display, outLayer, {} /*crop*/);
+
+    composer.setLayerTransform(display, outLayer, mFdp.PickValueInArray(kTransforms));
+
+    composer.setLayerVisibleRegion(display, outLayer, std::vector<IComposerClient::Rect>{});
+    composer.setLayerZOrder(display, outLayer, mFdp.ConsumeIntegral<uint32_t>());
+
+    invokeComposerHal2_2(&composer, display, outLayer);
+    invokeComposerHal2_3(&composer, display, outLayer);
+    invokeComposerHal2_4(&composer, display, outLayer);
+
+    composer.executeCommands();
+    composer.resetCommands();
+
+    composer.destroyLayer(display, outLayer);
+    composer.destroyVirtualDisplay(display);
+}
+
+void DisplayHardwareFuzzer::invokeComposerHal2_2(Hwc2::AidlComposer* composer, Display display,
+                                                 Hwc2::V2_4::hal::Layer outLayer) {
+    const std::vector<PerFrameMetadata> perFrameMetadatas;
+    composer->setLayerPerFrameMetadata(display, outLayer, perFrameMetadatas);
+
+    composer->getPerFrameMetadataKeys(display);
+    std::vector<RenderIntent> outRenderIntents;
+
+    composer->getRenderIntents(display, mFdp.PickValueInArray(kColormodes), &outRenderIntents);
+    mat4 outMatrix;
+    composer->getDataspaceSaturationMatrix(mFdp.PickValueInArray(kDataspaces), &outMatrix);
+}
+
+void DisplayHardwareFuzzer::invokeComposerHal2_3(Hwc2::AidlComposer* composer, Display display,
+                                                 Hwc2::V2_4::hal::Layer outLayer) {
+    composer->setDisplayContentSamplingEnabled(display, mFdp.ConsumeBool() /*enabled*/,
+                                               mFdp.ConsumeIntegral<uint8_t>() /*componentMask*/,
+                                               mFdp.ConsumeIntegral<uint64_t>() /*maxFrames*/);
+
+    DisplayedFrameStats outStats;
+    composer->getDisplayedContentSample(display, mFdp.ConsumeIntegral<uint64_t>() /*maxFrames*/,
+                                        mFdp.ConsumeIntegral<uint64_t>() /*timestamp*/, &outStats);
+
+    composer->setLayerPerFrameMetadataBlobs(display, outLayer, std::vector<PerFrameMetadataBlob>{});
+
+    composer->setDisplayBrightness(display, mFdp.ConsumeFloatingPoint<float>(),
+                                   Hwc2::Composer::DisplayBrightnessOptions{
+                                           .applyImmediately = mFdp.ConsumeIntegral<bool>()});
+}
+
+void DisplayHardwareFuzzer::invokeComposerHal2_4(Hwc2::AidlComposer* composer, Display display,
+                                                 Hwc2::V2_4::hal::Layer outLayer) {
+    VsyncPeriodChangeTimeline outTimeline;
+    composer->setActiveConfigWithConstraints(display, Config{},
+                                             IComposerClient::VsyncPeriodChangeConstraints{},
+                                             &outTimeline);
+
+    composer->setAutoLowLatencyMode(display, mFdp.ConsumeBool());
+
+    composer->setContentType(display, mFdp.PickValueInArray(kContentTypes));
+
+    std::vector<uint8_t> value;
+    value.push_back(mFdp.ConsumeIntegral<uint8_t>());
+    composer->setLayerGenericMetadata(display, outLayer, mFdp.ConsumeRandomLengthString() /*key*/,
+                                      mFdp.ConsumeBool() /*mandatory*/, value);
+}
+
+ui::Size DisplayHardwareFuzzer::getFuzzedSize() {
+    ui::Size size{mFdp.ConsumeIntegral<int32_t>() /*width*/,
+                  mFdp.ConsumeIntegral<int32_t>() /*height*/};
+    return size;
+}
+
+mat4 DisplayHardwareFuzzer::getFuzzedMatrix() {
+    mat4 matrix{mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+                mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()};
+    return matrix;
+}
+
+void DisplayHardwareFuzzer::setCursorPosition(HWC2::Layer* layer) {
+    layer->setCursorPosition(mFdp.ConsumeIntegral<int32_t>() /*x*/,
+                             mFdp.ConsumeIntegral<int32_t>() /*y*/);
+}
+
+void DisplayHardwareFuzzer::setBuffer(HWC2::Layer* layer) {
+    layer->setBuffer(mFdp.ConsumeIntegral<uint32_t>() /*slot*/, sp<GraphicBuffer>(),
+                     sp<Fence>::make());
+}
+
+void DisplayHardwareFuzzer::setSurfaceDamage(HWC2::Layer* layer) {
+    Rect rhs{mFdp.ConsumeIntegral<uint32_t>() /*width*/,
+             mFdp.ConsumeIntegral<uint32_t>() /*height*/};
+    const Region damage{rhs};
+    layer->setSurfaceDamage(damage);
+}
+
+void DisplayHardwareFuzzer::setVisibleRegion(HWC2::Layer* layer) {
+    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+    Rect rect{width, height};
+    const Region region{rect};
+    layer->setVisibleRegion(region);
+}
+
+void DisplayHardwareFuzzer::setDisplayFrame(HWC2::Layer* layer) {
+    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+    const Rect frame{width, height};
+    layer->setDisplayFrame(frame);
+}
+
+void DisplayHardwareFuzzer::setLayerGenericMetadata(HWC2::Layer* layer) {
+    std::vector<uint8_t> value;
+    value.push_back(mFdp.ConsumeIntegral<uint8_t>());
+    layer->setLayerGenericMetadata(mFdp.ConsumeRandomLengthString().c_str() /*name*/,
+                                   mFdp.ConsumeBool() /*mandatory*/, value);
+}
+
+void DisplayHardwareFuzzer::setSidebandStream(HWC2::Layer* layer) {
+    const native_handle_t stream{};
+    layer->setSidebandStream(&stream);
+}
+
+void DisplayHardwareFuzzer::invokeLayer(HWC2::Layer* layer) {
+    setCursorPosition(layer);
+    setBuffer(layer);
+    setSurfaceDamage(layer);
+
+    layer->setBlendMode(mFdp.PickValueInArray(kBlendModes));
+    layer->setColor({mFdp.ConsumeFloatingPoint<float>() /*red*/,
+                     mFdp.ConsumeFloatingPoint<float>() /*green*/,
+                     mFdp.ConsumeFloatingPoint<float>() /*blue*/,
+                     mFdp.ConsumeFloatingPoint<float>() /*alpha*/});
+    layer->setCompositionType(mFdp.PickValueInArray(kCompositions));
+    layer->setDataspace(mFdp.PickValueInArray(kDataspaces));
+
+    layer->setPerFrameMetadata(mFdp.ConsumeIntegral<int32_t>(), getFuzzedHdrMetadata(&mFdp));
+    setDisplayFrame(layer);
+
+    layer->setPlaneAlpha(mFdp.ConsumeFloatingPoint<float>());
+
+    setSidebandStream(layer);
+
+    layer->setSourceCrop(getFuzzedFloatRect(&mFdp));
+    layer->setTransform(mFdp.PickValueInArray(kTransforms));
+
+    setVisibleRegion(layer);
+
+    layer->setZOrder(mFdp.ConsumeIntegral<uint32_t>());
+
+    layer->setColorTransform(getFuzzedMatrix());
+
+    setLayerGenericMetadata(layer);
+}
+
+void DisplayHardwareFuzzer::invokeFrameBufferSurface() {
+    sp<IGraphicBufferProducer> bqProducer = sp<mock::GraphicBufferProducer>::make();
+    sp<IGraphicBufferConsumer> bqConsumer;
+    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+
+    sp<FramebufferSurface> surface =
+            new FramebufferSurface(mHwc, mPhysicalDisplayId, bqConsumer, getFuzzedSize() /*size*/,
+                                   getFuzzedSize() /*maxSize*/);
+    surface->beginFrame(mFdp.ConsumeBool());
+
+    surface->prepareFrame(mFdp.PickValueInArray(kCompositionTypes));
+    surface->advanceFrame();
+    surface->onFrameCommitted();
+    String8 result = String8(mFdp.ConsumeRandomLengthString().c_str());
+    surface->dumpAsString(result);
+    surface->resizeBuffers(getFuzzedSize());
+    surface->getClientTargetAcquireFence();
+}
+
+void DisplayHardwareFuzzer::invokeVirtualDisplaySurface() {
+    DisplayIdGenerator<HalVirtualDisplayId> mGenerator;
+    VirtualDisplayId VirtualDisplayId = mGenerator.generateId().value();
+
+    sp<SurfaceComposerClient> mClient = new SurfaceComposerClient();
+    sp<SurfaceControl> mSurfaceControl =
+            mClient->createSurface(String8("TestSurface"), 100, 100, PIXEL_FORMAT_RGBA_8888,
+                                   ISurfaceComposerClient::eFXSurfaceBufferState,
+                                   /*parent*/ nullptr);
+
+    sp<BLASTBufferQueue> mBlastBufferQueueAdapter =
+            new BLASTBufferQueue("TestBLASTBufferQueue", mSurfaceControl, 100, 100,
+                                 PIXEL_FORMAT_RGBA_8888);
+
+    sp<IGraphicBufferProducer> sink = mBlastBufferQueueAdapter->getIGraphicBufferProducer();
+    sp<IGraphicBufferProducer> bqProducer = mBlastBufferQueueAdapter->getIGraphicBufferProducer();
+    sp<IGraphicBufferConsumer> bqConsumer;
+    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+    BufferQueue::createBufferQueue(&sink, &bqConsumer);
+
+    sp<VirtualDisplaySurface> surface =
+            new VirtualDisplaySurface(mHwc, VirtualDisplayId, sink, bqProducer, bqConsumer,
+                                      mFdp.ConsumeRandomLengthString().c_str() /*name*/);
+
+    surface->beginFrame(mFdp.ConsumeBool());
+    surface->prepareFrame(mFdp.PickValueInArray(kCompositionTypes));
+    surface->resizeBuffers(getFuzzedSize());
+    surface->getClientTargetAcquireFence();
+    surface->advanceFrame();
+    surface->onFrameCommitted();
+    String8 result = String8(mFdp.ConsumeRandomLengthString().c_str());
+    surface->dumpAsString(result);
+}
+
+void DisplayHardwareFuzzer::invokeComposer() {
+    HalVirtualDisplayId halVirtualDisplayId = mGenerator.generateId().value();
+    HalDisplayId halDisplayID = HalDisplayId{halVirtualDisplayId};
+
+    android::hardware::graphics::composer::hal::TestHWC2ComposerCallback composerCallback{};
+    mHwc.setCallback(composerCallback);
+
+    ui::PixelFormat pixelFormat{};
+    if (!mHwc.allocateVirtualDisplay(halVirtualDisplayId, getFuzzedSize(), &pixelFormat)) {
+        return;
+    }
+
+    getDisplayIdentificationData();
+
+    mHwc.hasDisplayCapability(halDisplayID, mFdp.PickValueInArray(kDisplayCapability));
+
+    mHwc.allocatePhysicalDisplay(kHwDisplayId, mPhysicalDisplayId);
+
+    static auto hwcLayer = mHwc.createLayer(halDisplayID);
+    HWC2::Layer* layer = hwcLayer.get();
+    invokeLayer(layer);
+
+    getDeviceCompositionChanges(halDisplayID);
+
+    mHwc.setClientTarget(halDisplayID, mFdp.ConsumeIntegral<uint32_t>(), Fence::NO_FENCE,
+                         sp<GraphicBuffer>::make(), mFdp.PickValueInArray(kDataspaces));
+
+    mHwc.presentAndGetReleaseFences(halDisplayID, std::chrono::steady_clock::now(),
+                                    FenceTime::NO_FENCE);
+
+    mHwc.setPowerMode(mPhysicalDisplayId, mFdp.PickValueInArray(kPowerModes));
+
+    mHwc.setColorTransform(halDisplayID, getFuzzedMatrix());
+
+    mHwc.getPresentFence(halDisplayID);
+
+    mHwc.getLayerReleaseFence(halDisplayID, layer);
+
+    mHwc.setOutputBuffer(halVirtualDisplayId, sp<Fence>::make().get(), sp<GraphicBuffer>::make());
+
+    mHwc.clearReleaseFences(halDisplayID);
+
+    getHdrCapabilities(halDisplayID);
+
+    mHwc.getSupportedPerFrameMetadata(halDisplayID);
+
+    mHwc.getRenderIntents(halDisplayID, ui::ColorMode());
+
+    mHwc.getDataspaceSaturationMatrix(halDisplayID, ui::Dataspace());
+
+    getDisplayedContentSamplingAttributes(halDisplayID);
+
+    mHwc.setDisplayContentSamplingEnabled(halDisplayID, mFdp.ConsumeBool() /*enabled*/,
+                                          mFdp.ConsumeIntegral<uint8_t>() /*componentMask*/,
+                                          mFdp.ConsumeIntegral<uint64_t>() /*maxFrames*/);
+
+    getDisplayedContentSample(halDisplayID);
+
+    mHwc.setDisplayBrightness(mPhysicalDisplayId, mFdp.ConsumeFloatingPoint<float>(),
+                              Hwc2::Composer::DisplayBrightnessOptions{
+                                      .applyImmediately = mFdp.ConsumeIntegral<bool>()});
+
+    mHwc.onHotplug(kHwDisplayId, hal::Connection::CONNECTED);
+    mHwc.updatesDeviceProductInfoOnHotplugReconnect();
+
+    mHwc.onVsync(kHwDisplayId, mFdp.ConsumeIntegral<int64_t>());
+    mHwc.setVsyncEnabled(mPhysicalDisplayId,
+                         mFdp.ConsumeBool() ? hal::Vsync::ENABLE : hal::Vsync::DISABLE);
+
+    mHwc.isConnected(mPhysicalDisplayId);
+    mHwc.getModes(mPhysicalDisplayId);
+    mHwc.getActiveMode(mPhysicalDisplayId);
+    mHwc.getColorModes(mPhysicalDisplayId);
+    mHwc.hasCapability(mFdp.PickValueInArray(kCapability));
+
+    mHwc.setActiveColorMode(mPhysicalDisplayId, mFdp.PickValueInArray(kColormodes),
+                            mFdp.PickValueInArray(kRenderIntents));
+
+    mHwc.getDisplayConnectionType(mPhysicalDisplayId);
+    mHwc.isVsyncPeriodSwitchSupported(mPhysicalDisplayId);
+
+    getDisplayVsyncPeriod();
+
+    setActiveModeWithConstraints();
+
+    mHwc.setAutoLowLatencyMode(mPhysicalDisplayId, mFdp.ConsumeBool());
+
+    getSupportedContentTypes();
+
+    mHwc.setContentType(mPhysicalDisplayId, mFdp.PickValueInArray(kContentTypes));
+
+    dumpHwc();
+
+    mHwc.toPhysicalDisplayId(kHwDisplayId);
+    mHwc.fromPhysicalDisplayId(mPhysicalDisplayId);
+    mHwc.disconnectDisplay(halDisplayID);
+
+    static hal::HWDisplayId displayId = mFdp.ConsumeIntegral<hal::HWDisplayId>();
+    mHwc.onHotplug(displayId,
+                   mFdp.ConsumeBool() ? hal::Connection::DISCONNECTED : hal::Connection::CONNECTED);
+}
+
+template <size_t N>
+DisplayIdentificationData asDisplayIdentificationData(const unsigned char (&bytes)[N]) {
+    return DisplayIdentificationData(bytes, bytes + N - 1);
+}
+
+void DisplayHardwareFuzzer::invokeDisplayIdentification() {
+    static const DisplayIdentificationData data = asDisplayIdentificationData(kInternalEdid);
+    isEdid(data);
+    parseEdid(data);
+    parseDisplayIdentificationData(mFdp.ConsumeIntegral<uint8_t>(), data);
+    getPnpId(getVirtualDisplayId(mFdp.ConsumeIntegral<uint32_t>()));
+    getPnpId(mFdp.ConsumeIntegral<uint8_t>());
+}
+
+void DisplayHardwareFuzzer::process() {
+    invokeComposer();
+    invokeAidlComposer();
+    invokeDisplayIdentification();
+    invokeFrameBufferSurface();
+    invokeVirtualDisplaySurface();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    DisplayHardwareFuzzer displayHardwareFuzzer(data, size);
+    displayHardwareFuzzer.process();
+    return 0;
+}
+
+} // namespace android::fuzz
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer_utils.h
new file mode 100644
index 0000000..6a6e3db
--- /dev/null
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer_utils.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <utils/Condition.h>
+#include <chrono>
+#include <vector>
+
+#include <android/hardware/graphics/composer/2.4/IComposer.h>
+#include <composer-hal/2.1/ComposerClient.h>
+#include <composer-hal/2.2/ComposerClient.h>
+#include <composer-hal/2.3/ComposerClient.h>
+#include <composer-hal/2.4/ComposerClient.h>
+
+#include "DisplayHardware/HWC2.h"
+#include "surfaceflinger_fuzzers_utils.h"
+
+namespace {
+class LayerImpl;
+class Frame;
+class DelayedEventGenerator;
+} // namespace
+
+namespace android {
+class SurfaceComposerClient;
+} // namespace android
+
+namespace android::hardware::graphics::composer::hal {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::HWC2::ComposerCallback;
+
+class ComposerCallbackBridge : public IComposerCallback {
+public:
+    ComposerCallbackBridge(ComposerCallback* callback, bool vsyncSwitchingSupported)
+          : mCallback(callback), mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
+
+    Return<void> onHotplug(HWDisplayId display, Connection connection) override {
+        mCallback->onComposerHalHotplug(display, connection);
+        return Void();
+    }
+
+    Return<void> onRefresh(HWDisplayId display) override {
+        mCallback->onComposerHalRefresh(display);
+        return Void();
+    }
+
+    Return<void> onVsync(HWDisplayId display, int64_t timestamp) override {
+        if (!mVsyncSwitchingSupported) {
+            mCallback->onComposerHalVsync(display, timestamp, std::nullopt);
+        }
+        return Void();
+    }
+
+    Return<void> onVsync_2_4(HWDisplayId display, int64_t timestamp,
+                             VsyncPeriodNanos vsyncPeriodNanos) override {
+        if (mVsyncSwitchingSupported) {
+            mCallback->onComposerHalVsync(display, timestamp, vsyncPeriodNanos);
+        }
+        return Void();
+    }
+
+    Return<void> onVsyncPeriodTimingChanged(HWDisplayId display,
+                                            const VsyncPeriodChangeTimeline& timeline) override {
+        mCallback->onComposerHalVsyncPeriodTimingChanged(display, timeline);
+        return Void();
+    }
+
+    Return<void> onSeamlessPossible(HWDisplayId display) override {
+        mCallback->onComposerHalSeamlessPossible(display);
+        return Void();
+    }
+
+private:
+    ComposerCallback* const mCallback;
+    const bool mVsyncSwitchingSupported;
+};
+
+struct TestHWC2ComposerCallback : public HWC2::ComposerCallback {
+    virtual ~TestHWC2ComposerCallback() = default;
+    void onComposerHalHotplug(HWDisplayId, Connection){};
+    void onComposerHalRefresh(HWDisplayId) {}
+    void onComposerHalVsync(HWDisplayId, int64_t, std::optional<VsyncPeriodNanos>) {}
+    void onComposerHalVsyncPeriodTimingChanged(HWDisplayId, const VsyncPeriodChangeTimeline&) {}
+    void onComposerHalSeamlessPossible(HWDisplayId) {}
+    void onComposerHalVsyncIdle(HWDisplayId) {}
+};
+
+} // namespace android::hardware::graphics::composer::hal
