Added surfaceflinger_layer_fuzzer
Test: ./surfaceflinger_layer_fuzzer
Bug: 189053744
Change-Id: I783b18389dd260b86eec2786c307d71d53785077
diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp
index b0d216e..1892e4c 100644
--- a/services/surfaceflinger/fuzzer/Android.bp
+++ b/services/surfaceflinger/fuzzer/Android.bp
@@ -102,3 +102,19 @@
"surfaceflinger_scheduler_fuzzer.cpp",
],
}
+
+cc_fuzz {
+ name: "surfaceflinger_layer_fuzzer",
+ defaults: [
+ "surfaceflinger_fuzz_defaults",
+ ],
+ header_libs: [
+ "libgui_headers",
+ ],
+ static_libs: [
+ "librenderengine",
+ ],
+ srcs: [
+ "surfaceflinger_layer_fuzzer.cpp",
+ ],
+}
diff --git a/services/surfaceflinger/fuzzer/README.md b/services/surfaceflinger/fuzzer/README.md
index 6231ca5..78a7596 100644
--- a/services/surfaceflinger/fuzzer/README.md
+++ b/services/surfaceflinger/fuzzer/README.md
@@ -3,6 +3,7 @@
+ [SurfaceFlinger](#SurfaceFlinger)
+ [DisplayHardware](#DisplayHardware)
+ [Scheduler](#Scheduler)
++ [Layer](#Layer)
# <a name="SurfaceFlinger"></a> Fuzzer for SurfaceFlinger
@@ -70,3 +71,25 @@
$ adb sync data
$ adb shell /data/fuzz/arm64/surfaceflinger_scheduler_fuzzer/surfaceflinger_scheduler_fuzzer
```
+
+# <a name="Layer"></a> Fuzzer for Layer
+
+Layer supports the following parameters:
+1. Display Connection Types (parameter name: `fakeDisplay`)
+2. State Sets (parameter name: `traverseInZOrder`)
+3. State Subsets (parameter name: `prepareCompositionState`)
+4. Disconnect modes (parameter name: `disconnect`)
+5. Data Spaces (parameter name: `setDataspace`)
+
+You can find the possible values in the fuzzer's source code.
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) surfaceflinger_layer_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/surfaceflinger_layer_fuzzer/surfaceflinger_layer_fuzzer
+```
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
index 30a6fbd..afc1abd 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
@@ -29,35 +29,6 @@
LatchUnsignaledConfig::Disabled,
};
-static constexpr ui::PixelFormat kPixelFormats[] = {ui::PixelFormat::RGBA_8888,
- ui::PixelFormat::RGBX_8888,
- ui::PixelFormat::RGB_888,
- ui::PixelFormat::RGB_565,
- ui::PixelFormat::BGRA_8888,
- ui::PixelFormat::YCBCR_422_SP,
- ui::PixelFormat::YCRCB_420_SP,
- ui::PixelFormat::YCBCR_422_I,
- ui::PixelFormat::RGBA_FP16,
- ui::PixelFormat::RAW16,
- ui::PixelFormat::BLOB,
- ui::PixelFormat::IMPLEMENTATION_DEFINED,
- ui::PixelFormat::YCBCR_420_888,
- ui::PixelFormat::RAW_OPAQUE,
- ui::PixelFormat::RAW10,
- ui::PixelFormat::RAW12,
- ui::PixelFormat::RGBA_1010102,
- ui::PixelFormat::Y8,
- ui::PixelFormat::Y16,
- ui::PixelFormat::YV12,
- ui::PixelFormat::DEPTH_16,
- ui::PixelFormat::DEPTH_24,
- ui::PixelFormat::DEPTH_24_STENCIL_8,
- ui::PixelFormat::DEPTH_32F,
- ui::PixelFormat::DEPTH_32F_STENCIL_8,
- ui::PixelFormat::STENCIL_8,
- ui::PixelFormat::YCBCR_P010,
- ui::PixelFormat::HSV_888};
-
static constexpr ui::Rotation kRotations[] = {ui::Rotation::Rotation0, ui::Rotation::Rotation90,
ui::Rotation::Rotation180, ui::Rotation::Rotation270};
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 0a458c2..2fcf856 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -123,6 +123,35 @@
ui::ColorMode::BT2100_HLG,
ui::ColorMode::DISPLAY_BT2020};
+static constexpr ui::PixelFormat kPixelFormats[] = {ui::PixelFormat::RGBA_8888,
+ ui::PixelFormat::RGBX_8888,
+ ui::PixelFormat::RGB_888,
+ ui::PixelFormat::RGB_565,
+ ui::PixelFormat::BGRA_8888,
+ ui::PixelFormat::YCBCR_422_SP,
+ ui::PixelFormat::YCRCB_420_SP,
+ ui::PixelFormat::YCBCR_422_I,
+ ui::PixelFormat::RGBA_FP16,
+ ui::PixelFormat::RAW16,
+ ui::PixelFormat::BLOB,
+ ui::PixelFormat::IMPLEMENTATION_DEFINED,
+ ui::PixelFormat::YCBCR_420_888,
+ ui::PixelFormat::RAW_OPAQUE,
+ ui::PixelFormat::RAW10,
+ ui::PixelFormat::RAW12,
+ ui::PixelFormat::RGBA_1010102,
+ ui::PixelFormat::Y8,
+ ui::PixelFormat::Y16,
+ ui::PixelFormat::YV12,
+ ui::PixelFormat::DEPTH_16,
+ ui::PixelFormat::DEPTH_24,
+ ui::PixelFormat::DEPTH_24_STENCIL_8,
+ ui::PixelFormat::DEPTH_32F,
+ ui::PixelFormat::DEPTH_32F_STENCIL_8,
+ ui::PixelFormat::STENCIL_8,
+ ui::PixelFormat::YCBCR_P010,
+ ui::PixelFormat::HSV_888};
+
FloatRect getFuzzedFloatRect(FuzzedDataProvider *fdp) {
return FloatRect(fdp->ConsumeFloatingPoint<float>() /*left*/,
fdp->ConsumeFloatingPoint<float>() /*right*/,
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
new file mode 100644
index 0000000..46d52dd
--- /dev/null
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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 <BufferStateLayer.h>
+#include <Client.h>
+#include <DisplayDevice.h>
+#include <EffectLayer.h>
+#include <LayerRejecter.h>
+#include <LayerRenderArea.h>
+#include <MonitoredProducer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gui/IProducerListener.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/WindowInfo.h>
+#include <renderengine/mock/FakeExternalTexture.h>
+#include <ui/DisplayStatInfo.h>
+
+#include <FuzzableDataspaces.h>
+#include <surfaceflinger_fuzzers_utils.h>
+
+namespace android::fuzzer {
+using namespace renderengine;
+
+constexpr uint16_t kRandomStringLength = 256;
+
+class LayerFuzzer {
+public:
+ LayerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void init();
+ void invokeBufferStateLayer();
+ void invokeEffectLayer();
+ LayerCreationArgs createLayerCreationArgs(TestableSurfaceFlinger* flinger, sp<Client> client);
+ Rect getFuzzedRect();
+ FrameTimelineInfo getFuzzedFrameTimelineInfo();
+
+private:
+ FuzzedDataProvider mFdp;
+};
+
+Rect LayerFuzzer::getFuzzedRect() {
+ return Rect(mFdp.ConsumeIntegral<int32_t>() /*left*/, mFdp.ConsumeIntegral<int32_t>() /*top*/,
+ mFdp.ConsumeIntegral<int32_t>() /*right*/,
+ mFdp.ConsumeIntegral<int32_t>() /*bottom*/);
+}
+
+FrameTimelineInfo LayerFuzzer::getFuzzedFrameTimelineInfo() {
+ return FrameTimelineInfo{.vsyncId = mFdp.ConsumeIntegral<int64_t>(),
+ .inputEventId = mFdp.ConsumeIntegral<int32_t>()};
+}
+
+LayerCreationArgs LayerFuzzer::createLayerCreationArgs(TestableSurfaceFlinger* flinger,
+ sp<Client> client) {
+ flinger->setupScheduler(std::make_unique<android::mock::VsyncController>(),
+ std::make_unique<android::mock::VSyncTracker>(),
+ std::make_unique<android::mock::EventThread>(),
+ std::make_unique<android::mock::EventThread>());
+
+ return LayerCreationArgs(flinger->flinger(), client,
+ mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/,
+ mFdp.ConsumeIntegral<uint32_t>() /*flags*/, {} /*metadata*/);
+}
+
+void LayerFuzzer::invokeEffectLayer() {
+ TestableSurfaceFlinger flinger;
+ sp<Client> client = sp<Client>::make(flinger.flinger());
+ const LayerCreationArgs layerCreationArgs = createLayerCreationArgs(&flinger, client);
+ sp<EffectLayer> effectLayer = sp<EffectLayer>::make(layerCreationArgs);
+
+ effectLayer->setColor({(mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*x*/,
+ mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*y*/,
+ mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*z*/)});
+ effectLayer->setDataspace(mFdp.PickValueInArray(kDataspaces));
+ sp<EffectLayer> parent = sp<EffectLayer>::make(layerCreationArgs);
+ effectLayer->setChildrenDrawingParent(parent);
+
+ const FrameTimelineInfo frameInfo = getFuzzedFrameTimelineInfo();
+ const int64_t postTime = mFdp.ConsumeIntegral<int64_t>();
+ effectLayer->setFrameTimelineVsyncForBufferTransaction(frameInfo, postTime);
+ effectLayer->setFrameTimelineVsyncForBufferlessTransaction(frameInfo, postTime);
+ auto surfaceFrame = effectLayer->createSurfaceFrameForTransaction(frameInfo, postTime);
+ auto surfaceFrame1 =
+ effectLayer->createSurfaceFrameForBuffer(frameInfo, postTime,
+ mFdp.ConsumeRandomLengthString(
+ kRandomStringLength) /*bufferName*/);
+ effectLayer->addSurfaceFramePresentedForBuffer(surfaceFrame,
+ mFdp.ConsumeIntegral<int64_t>() /*acquireTime*/,
+ mFdp.ConsumeIntegral<int64_t>() /*currentTime*/);
+ effectLayer->addSurfaceFrameDroppedForBuffer(surfaceFrame1);
+
+ parent.clear();
+ client.clear();
+ effectLayer.clear();
+}
+
+void LayerFuzzer::invokeBufferStateLayer() {
+ TestableSurfaceFlinger flinger;
+ sp<Client> client = sp<Client>::make(flinger.flinger());
+ sp<BufferStateLayer> layer =
+ sp<BufferStateLayer>::make(createLayerCreationArgs(&flinger, client));
+ sp<Fence> fence = sp<Fence>::make();
+ const std::shared_ptr<FenceTime> fenceTime = std::make_shared<FenceTime>(fence);
+
+ const CompositorTiming compositor = {mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>()};
+ std::packaged_task<renderengine::RenderEngineResult()> renderResult([&] {
+ return renderengine::RenderEngineResult{mFdp.ConsumeIntegral<int32_t>(),
+ base::unique_fd(fence->get())};
+ });
+ layer->onLayerDisplayed(renderResult.get_future());
+ layer->releasePendingBuffer(mFdp.ConsumeIntegral<int64_t>());
+ layer->finalizeFrameEventHistory(fenceTime, compositor);
+ layer->onPostComposition(nullptr, fenceTime, fenceTime, compositor);
+ layer->isBufferDue(mFdp.ConsumeIntegral<int64_t>());
+
+ layer->setTransform(mFdp.ConsumeIntegral<uint32_t>());
+ layer->setTransformToDisplayInverse(mFdp.ConsumeBool());
+ layer->setCrop(getFuzzedRect());
+
+ layer->setHdrMetadata(getFuzzedHdrMetadata(&mFdp));
+ layer->setDataspace(mFdp.PickValueInArray(kDataspaces));
+ if (mFdp.ConsumeBool()) {
+ layer->setSurfaceDamageRegion(Region());
+ layer->setTransparentRegionHint(Region());
+ } else {
+ layer->setSurfaceDamageRegion(Region(getFuzzedRect()));
+ layer->setTransparentRegionHint(Region(getFuzzedRect()));
+ }
+ layer->setApi(mFdp.ConsumeIntegral<int32_t>());
+
+ native_handle_t* testHandle = native_handle_create(0, 1);
+ const bool ownsHandle = mFdp.ConsumeBool();
+ sp<NativeHandle> nativeHandle = sp<NativeHandle>::make(testHandle, ownsHandle);
+ layer->setSidebandStream(nativeHandle);
+ layer->addFrameEvent(fence, mFdp.ConsumeIntegral<int64_t>() /*postedTime*/,
+ mFdp.ConsumeIntegral<int64_t>() /*requestedTime*/);
+ layer->computeSourceBounds(getFuzzedFloatRect(&mFdp));
+
+ layer->fenceHasSignaled();
+ layer->framePresentTimeIsCurrent(mFdp.ConsumeIntegral<int64_t>());
+ layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>());
+ const std::vector<sp<CallbackHandle>> callbacks;
+ layer->setTransactionCompletedListeners(callbacks);
+
+ std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
+ renderengine::mock::FakeExternalTexture>(mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint64_t>(),
+ static_cast<android::PixelFormat>(
+ mFdp.PickValueInArray(kPixelFormats)),
+ mFdp.ConsumeIntegral<uint64_t>());
+ layer->setBuffer(texture, {} /*bufferData*/, mFdp.ConsumeIntegral<nsecs_t>() /*postTime*/,
+ mFdp.ConsumeIntegral<nsecs_t>() /*desiredTime*/,
+ mFdp.ConsumeBool() /*isAutoTimestamp*/,
+ {mFdp.ConsumeIntegral<nsecs_t>()} /*dequeue*/, {} /*info*/);
+
+ LayerRenderArea layerArea(*(flinger.flinger()), layer, getFuzzedRect(),
+ {mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<int32_t>()} /*reqSize*/,
+ mFdp.PickValueInArray(kDataspaces), mFdp.ConsumeBool(),
+ getFuzzedRect(), mFdp.ConsumeBool());
+ layerArea.render([]() {} /*drawLayers*/);
+
+ if (!ownsHandle) {
+ native_handle_close(testHandle);
+ native_handle_delete(testHandle);
+ }
+ nativeHandle.clear();
+ fence.clear();
+ client.clear();
+ layer.clear();
+}
+
+void LayerFuzzer::init() {
+ invokeBufferStateLayer();
+ invokeEffectLayer();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ LayerFuzzer layerFuzzer(data, size);
+ layerFuzzer.init();
+ return 0;
+}
+
+} // namespace android::fuzzer