diff options
| -rw-r--r-- | libs/ui/Android.bp | 5 | ||||
| -rw-r--r-- | libs/ui/include/ui/fuzzer/FuzzableDataspaces.h | 80 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/Android.bp | 94 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/README.md | 53 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp | 662 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer_utils.h | 103 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp | 295 | ||||
| -rw-r--r-- | services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h | 803 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/Android.bp | 31 |
9 files changed, 2114 insertions, 12 deletions
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 006c4780ad..980fc8bcf1 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -29,6 +29,11 @@ license { ], } +cc_library_headers { + name: "libui_fuzzableDataspaces_headers", + export_include_dirs: ["include/ui/fuzzer/"], +} + cc_defaults { name: "libui-defaults", clang: true, diff --git a/libs/ui/include/ui/fuzzer/FuzzableDataspaces.h b/libs/ui/include/ui/fuzzer/FuzzableDataspaces.h new file mode 100644 index 0000000000..4200d6a72d --- /dev/null +++ b/libs/ui/include/ui/fuzzer/FuzzableDataspaces.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 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 <ui/GraphicTypes.h> +using namespace android; + +constexpr ui::Dataspace kDataspaces[] = { + ui::Dataspace::UNKNOWN, + ui::Dataspace::ARBITRARY, + ui::Dataspace::STANDARD_UNSPECIFIED, + ui::Dataspace::STANDARD_BT709, + ui::Dataspace::STANDARD_BT601_625, + ui::Dataspace::STANDARD_BT601_625_UNADJUSTED, + ui::Dataspace::STANDARD_BT601_525, + ui::Dataspace::STANDARD_BT601_525_UNADJUSTED, + ui::Dataspace::STANDARD_BT2020, + ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE, + ui::Dataspace::STANDARD_BT470M, + ui::Dataspace::STANDARD_FILM, + ui::Dataspace::STANDARD_DCI_P3, + ui::Dataspace::STANDARD_ADOBE_RGB, + ui::Dataspace::TRANSFER_UNSPECIFIED, + ui::Dataspace::TRANSFER_LINEAR, + ui::Dataspace::TRANSFER_SRGB, + ui::Dataspace::TRANSFER_SMPTE_170M, + ui::Dataspace::TRANSFER_GAMMA2_2, + ui::Dataspace::TRANSFER_GAMMA2_6, + ui::Dataspace::TRANSFER_GAMMA2_8, + ui::Dataspace::TRANSFER_ST2084, + ui::Dataspace::TRANSFER_HLG, + ui::Dataspace::RANGE_UNSPECIFIED, + ui::Dataspace::RANGE_FULL, + ui::Dataspace::RANGE_LIMITED, + ui::Dataspace::RANGE_EXTENDED, + ui::Dataspace::SRGB_LINEAR, + ui::Dataspace::V0_SRGB_LINEAR, + ui::Dataspace::V0_SCRGB_LINEAR, + ui::Dataspace::SRGB, + ui::Dataspace::V0_SRGB, + ui::Dataspace::V0_SCRGB, + ui::Dataspace::JFIF, + ui::Dataspace::V0_JFIF, + ui::Dataspace::BT601_625, + ui::Dataspace::V0_BT601_625, + ui::Dataspace::BT601_525, + ui::Dataspace::V0_BT601_525, + ui::Dataspace::BT709, + ui::Dataspace::V0_BT709, + ui::Dataspace::DCI_P3_LINEAR, + ui::Dataspace::DCI_P3, + ui::Dataspace::DISPLAY_P3_LINEAR, + ui::Dataspace::DISPLAY_P3, + ui::Dataspace::ADOBE_RGB, + ui::Dataspace::BT2020_LINEAR, + ui::Dataspace::BT2020, + ui::Dataspace::BT2020_PQ, + ui::Dataspace::DEPTH, + ui::Dataspace::SENSOR, + ui::Dataspace::BT2020_ITU, + ui::Dataspace::BT2020_ITU_PQ, + ui::Dataspace::BT2020_ITU_HLG, + ui::Dataspace::BT2020_HLG, + ui::Dataspace::DISPLAY_BT2020, + ui::Dataspace::DYNAMIC_DEPTH, + ui::Dataspace::JPEG_APP_SEGMENTS, + ui::Dataspace::HEIF, +}; diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp new file mode 100644 index 0000000000..0ead1631e7 --- /dev/null +++ b/services/surfaceflinger/fuzzer/Android.bp @@ -0,0 +1,94 @@ +/* + * 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. + * + */ + +cc_defaults { + name: "surfaceflinger_fuzz_defaults", + include_dirs: [ + "frameworks/native/services/surfaceflinger/tests/unittests", + ], + static_libs: [ + "android.hardware.graphics.composer@2.1-resources", + "libgmock", + "libgui_mocks", + "libgmock_ndk", + "libgmock_main", + "libgtest_ndk_c++", + "libgmock_main_ndk", + "librenderengine_mocks", + "perfetto_trace_protos", + "libcompositionengine_mocks", + "perfetto_trace_protos", + ], + shared_libs: [ + "libprotoutil", + "libstatssocket", + "libstatspull", + "libtimestats", + "libtimestats_proto", + "libprotobuf-cpp-full", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", + ], + srcs: [ + ":libsurfaceflinger_sources", + ":libsurfaceflinger_mock_sources", + ], + defaults: [ + "libsurfaceflinger_defaults", + ], + header_libs: [ + "libui_fuzzableDataspaces_headers", + "libsurfaceflinger_headers", + "libui_headers", + ], + cflags: [ + "-Wno-unused-result", + "-Wno-conversion", + "-Wno-sign-compare", + ], + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, +} + +cc_fuzz { + name: "surfaceflinger_fuzzer", + defaults: [ + "surfaceflinger_fuzz_defaults", + ], + srcs: [ + "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 new file mode 100644 index 0000000000..4ecf770ca9 --- /dev/null +++ b/services/surfaceflinger/fuzzer/README.md @@ -0,0 +1,53 @@ +# Fuzzers for SurfaceFlinger +## Table of contents ++ [SurfaceFlinger](#SurfaceFlinger) ++ [DisplayHardware](#DisplayHardware) + +# <a name="SurfaceFlinger"></a> Fuzzer for SurfaceFlinger + +SurfaceFlinger supports the following data sources: +1. Pixel Formats (parameter name: `defaultCompositionPixelFormat`) +2. Data Spaces (parameter name: `defaultCompositionDataspace`) +3. Rotations (parameter name: `internalDisplayOrientation`) +3. Surface composer tags (parameter name: `onTransact`) + +You can find the possible values in the fuzzer's source code. + +#### Steps to run +1. Build the fuzzer +``` + $ mm -j$(nproc) surfaceflinger_fuzzer +``` +2. To run on device +``` + $ 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 0000000000..a18a28a077 --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp @@ -0,0 +1,662 @@ +/* + * 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 "DisplayHardware/AidlComposerHal.h" +#include "DisplayHardware/DisplayIdentification.h" +#include "DisplayHardware/DisplayMode.h" +#include "DisplayHardware/FramebufferSurface.h" +#include "DisplayHardware/HWComposer.h" +#include "DisplayHardware/Hash.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( + sp<android::hardware::graphics::composer::hal::ComposerCallbackBridge>:: + make(&composerCallback, + composer.isSupported( + Hwc2::Composer::OptionalFeature::RefreshRateSwitching))); + + 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.ConsumeIntegral<uint8_t>() /*red*/, + mFdp.ConsumeIntegral<uint8_t>() /*green*/, + mFdp.ConsumeIntegral<uint8_t>() /*blue*/, + mFdp.ConsumeIntegral<uint8_t>() /*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>()); +} + +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.ConsumeIntegral<uint8_t>() /*red*/, mFdp.ConsumeIntegral<uint8_t>() /*green*/, + mFdp.ConsumeIntegral<uint8_t>() /*blue*/, mFdp.ConsumeIntegral<uint8_t>() /*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>()); + + 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); +} + +uint32_t hashStr(const char* str) { + return static_cast<uint32_t>(cityHash64Len0To16(str)); +} + +void DisplayHardwareFuzzer::invokeDisplayIdentification() { + static const DisplayIdentificationData data = asDisplayIdentificationData(kInternalEdid); + isEdid(data); + parseEdid(data); + hashStr(mFdp.ConsumeRandomLengthString().c_str()); + 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 0000000000..d04727091c --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer_utils.h @@ -0,0 +1,103 @@ +/* + * 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) {} +}; + +} // namespace android::hardware::graphics::composer::hal diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp new file mode 100644 index 0000000000..ba8041460b --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp @@ -0,0 +1,295 @@ +/* + * 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 <FuzzableDataspaces.h> +#include <binder/IServiceManager.h> +#include <fuzzer/FuzzedDataProvider.h> +#include <ui/DisplayStatInfo.h> +#include "surfaceflinger_fuzzers_utils.h" + +namespace android::fuzz { + +static constexpr LatchUnsignaledConfig kLatchUnsignaledConfig[] = { + LatchUnsignaledConfig::Always, + LatchUnsignaledConfig::Auto, + 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}; + +static constexpr BnSurfaceComposer::ISurfaceComposerTag kSurfaceComposerTags[]{ + BnSurfaceComposer::BOOT_FINISHED, + BnSurfaceComposer::CREATE_CONNECTION, + BnSurfaceComposer::GET_STATIC_DISPLAY_INFO, + BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION, + BnSurfaceComposer::CREATE_DISPLAY, + BnSurfaceComposer::DESTROY_DISPLAY, + BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, + BnSurfaceComposer::SET_TRANSACTION_STATE, + BnSurfaceComposer::AUTHENTICATE_SURFACE, + BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS, + BnSurfaceComposer::GET_DISPLAY_MODES, + BnSurfaceComposer::GET_ACTIVE_DISPLAY_MODE, + BnSurfaceComposer::GET_DISPLAY_STATE, + BnSurfaceComposer::CAPTURE_DISPLAY, + BnSurfaceComposer::CAPTURE_LAYERS, + BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS, + BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, + BnSurfaceComposer::SET_POWER_MODE, + BnSurfaceComposer::GET_DISPLAY_STATS, + BnSurfaceComposer::GET_HDR_CAPABILITIES, + BnSurfaceComposer::GET_DISPLAY_COLOR_MODES, + BnSurfaceComposer::GET_ACTIVE_COLOR_MODE, + BnSurfaceComposer::SET_ACTIVE_COLOR_MODE, + BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS, + BnSurfaceComposer::INJECT_VSYNC, + BnSurfaceComposer::GET_LAYER_DEBUG_INFO, + BnSurfaceComposer::GET_COMPOSITION_PREFERENCE, + BnSurfaceComposer::GET_COLOR_MANAGEMENT, + BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES, + BnSurfaceComposer::SET_DISPLAY_CONTENT_SAMPLING_ENABLED, + BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE, + BnSurfaceComposer::GET_PROTECTED_CONTENT_SUPPORT, + BnSurfaceComposer::IS_WIDE_COLOR_DISPLAY, + BnSurfaceComposer::GET_DISPLAY_NATIVE_PRIMARIES, + BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, + BnSurfaceComposer::ADD_REGION_SAMPLING_LISTENER, + BnSurfaceComposer::REMOVE_REGION_SAMPLING_LISTENER, + BnSurfaceComposer::SET_DESIRED_DISPLAY_MODE_SPECS, + BnSurfaceComposer::GET_DESIRED_DISPLAY_MODE_SPECS, + BnSurfaceComposer::GET_DISPLAY_BRIGHTNESS_SUPPORT, + BnSurfaceComposer::SET_DISPLAY_BRIGHTNESS, + BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, + BnSurfaceComposer::NOTIFY_POWER_BOOST, + BnSurfaceComposer::SET_GLOBAL_SHADOW_SETTINGS, + BnSurfaceComposer::GET_AUTO_LOW_LATENCY_MODE_SUPPORT, + BnSurfaceComposer::SET_AUTO_LOW_LATENCY_MODE, + BnSurfaceComposer::GET_GAME_CONTENT_TYPE_SUPPORT, + BnSurfaceComposer::SET_GAME_CONTENT_TYPE, + BnSurfaceComposer::SET_FRAME_RATE, + BnSurfaceComposer::ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN, + BnSurfaceComposer::SET_FRAME_TIMELINE_INFO, + BnSurfaceComposer::ADD_TRANSACTION_TRACE_LISTENER, + BnSurfaceComposer::GET_GPU_CONTEXT_PRIORITY, + BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT, + BnSurfaceComposer::GET_DYNAMIC_DISPLAY_INFO, + BnSurfaceComposer::ADD_FPS_LISTENER, + BnSurfaceComposer::REMOVE_FPS_LISTENER, + BnSurfaceComposer::OVERRIDE_HDR_TYPES, + BnSurfaceComposer::ADD_HDR_LAYER_INFO_LISTENER, + BnSurfaceComposer::REMOVE_HDR_LAYER_INFO_LISTENER, + BnSurfaceComposer::ON_PULL_ATOM, + BnSurfaceComposer::ADD_TUNNEL_MODE_ENABLED_LISTENER, + BnSurfaceComposer::REMOVE_TUNNEL_MODE_ENABLED_LISTENER, + BnSurfaceComposer::ADD_WINDOW_INFOS_LISTENER, + BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, +}; + +static constexpr uint32_t kMinCode = 1000; +static constexpr uint32_t kMaxCode = 1050; + +class SurfaceFlingerFuzzer { +public: + SurfaceFlingerFuzzer(const uint8_t *data, size_t size) : mFdp(data, size) { + mFlinger = mTestableFlinger.flinger(); + }; + void process(const uint8_t *data, size_t size); + +private: + void setUp(); + void invokeFlinger(); + void setTransactionState(); + void setInternalDisplayPrimaries(); + void setDisplayStateLocked(); + void onTransact(const uint8_t *data, size_t size); + + FuzzedDataProvider mFdp; + TestableSurfaceFlinger mTestableFlinger; + sp<SurfaceFlinger> mFlinger = nullptr; +}; + +void SurfaceFlingerFuzzer::invokeFlinger() { + mFlinger->setSchedFifo(mFdp.ConsumeBool()); + mFlinger->setSchedAttr(mFdp.ConsumeBool()); + mFlinger->getServiceName(); + mFlinger->hasSyncFramework = mFdp.ConsumeBool(); + mFlinger->dispSyncPresentTimeOffset = mFdp.ConsumeIntegral<int64_t>(); + mFlinger->useHwcForRgbToYuv = mFdp.ConsumeBool(); + mFlinger->maxFrameBufferAcquiredBuffers = mFdp.ConsumeIntegral<int64_t>(); + mFlinger->maxGraphicsWidth = mFdp.ConsumeIntegral<uint32_t>(); + mFlinger->maxGraphicsHeight = mFdp.ConsumeIntegral<uint32_t>(); + mFlinger->hasWideColorDisplay = mFdp.ConsumeBool(); + mFlinger->internalDisplayOrientation = mFdp.PickValueInArray(kRotations); + mFlinger->useContextPriority = mFdp.ConsumeBool(); + + mFlinger->defaultCompositionDataspace = mFdp.PickValueInArray(kDataspaces); + mFlinger->defaultCompositionPixelFormat = mFdp.PickValueInArray(kPixelFormats); + mFlinger->wideColorGamutCompositionDataspace = mFdp.PickValueInArray(kDataspaces); + mFlinger->wideColorGamutCompositionPixelFormat = mFdp.PickValueInArray(kPixelFormats); + + mFlinger->enableSdrDimming = mFdp.ConsumeBool(); + mFlinger->enableLatchUnsignaledConfig = mFdp.PickValueInArray(kLatchUnsignaledConfig); + + mFlinger->scheduleComposite(mFdp.ConsumeBool() + ? scheduler::ISchedulerCallback::FrameHint::kActive + : scheduler::ISchedulerCallback::FrameHint::kNone); + + mFlinger->scheduleRepaint(); + mFlinger->scheduleSample(); + + uint32_t texture = mFlinger->getNewTexture(); + mFlinger->deleteTextureAsync(texture); + + sp<IBinder> handle = defaultServiceManager()->checkService( + String16(mFdp.ConsumeRandomLengthString().c_str())); + mFlinger->fromHandle(handle); + mFlinger->windowInfosReported(); + mFlinger->disableExpensiveRendering(); +} + +void SurfaceFlingerFuzzer::setInternalDisplayPrimaries() { + ui::DisplayPrimaries primaries; + primaries.red.X = mFdp.ConsumeFloatingPoint<float>(); + primaries.red.Y = mFdp.ConsumeFloatingPoint<float>(); + primaries.red.Z = mFdp.ConsumeFloatingPoint<float>(); + primaries.green.X = mFdp.ConsumeFloatingPoint<float>(); + primaries.green.Y = mFdp.ConsumeFloatingPoint<float>(); + primaries.green.Z = mFdp.ConsumeFloatingPoint<float>(); + primaries.blue.X = mFdp.ConsumeFloatingPoint<float>(); + primaries.blue.Y = mFdp.ConsumeFloatingPoint<float>(); + primaries.blue.Z = mFdp.ConsumeFloatingPoint<float>(); + primaries.white.X = mFdp.ConsumeFloatingPoint<float>(); + primaries.white.Y = mFdp.ConsumeFloatingPoint<float>(); + primaries.white.Z = mFdp.ConsumeFloatingPoint<float>(); + mTestableFlinger.setInternalDisplayPrimaries(primaries); +} + +void SurfaceFlingerFuzzer::setTransactionState() { + Vector<ComposerState> states; + Vector<DisplayState> displays; + ComposerState composerState; + composerState.state.what = layer_state_t::eLayerCreated; + composerState.state.surface = nullptr; + states.add(composerState); + uint32_t flags = mFdp.ConsumeIntegral<uint32_t>(); + const sp<IBinder> applyToken = nullptr; + int64_t desiredPresentTime = mFdp.ConsumeIntegral<int64_t>(); + bool isAutoTimestamp = mFdp.ConsumeBool(); + bool hasListenerCallbacks = mFdp.ConsumeBool(); + std::vector<ListenerCallbacks> listenerCallbacks{}; + uint64_t transactionId = mFdp.ConsumeIntegral<uint64_t>(); + + mTestableFlinger.setTransactionState(FrameTimelineInfo{}, states, displays, flags, applyToken, + InputWindowCommands{}, desiredPresentTime, isAutoTimestamp, + {}, hasListenerCallbacks, listenerCallbacks, + transactionId); +} + +void SurfaceFlingerFuzzer::setDisplayStateLocked() { + DisplayState state{}; + mTestableFlinger.setDisplayStateLocked(state); +} + +void SurfaceFlingerFuzzer::onTransact(const uint8_t *data, size_t size) { + Parcel fuzzedData, reply; + fuzzedData.writeInterfaceToken(String16("android.ui.ISurfaceComposer")); + fuzzedData.setData(data, size); + fuzzedData.setDataPosition(0); + uint32_t code = mFdp.ConsumeBool() ? mFdp.PickValueInArray(kSurfaceComposerTags) + : mFdp.ConsumeIntegralInRange<uint32_t>(kMinCode, kMaxCode); + mTestableFlinger.onTransact(code, fuzzedData, &reply, 0); +} + +void SurfaceFlingerFuzzer::setUp() { + mTestableFlinger.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>()); + + mTestableFlinger.setupTimeStats(std::make_unique<android::mock::TimeStats>()); + + std::unique_ptr<android::renderengine::RenderEngine> renderEngine = + std::make_unique<android::renderengine::mock::RenderEngine>(); + mTestableFlinger.setupRenderEngine(std::move(renderEngine)); + mTestableFlinger.setupComposer(std::make_unique<android::Hwc2::mock::Composer>()); +} + +void SurfaceFlingerFuzzer::process(const uint8_t *data, size_t size) { + setUp(); + + invokeFlinger(); + + mTestableFlinger.fuzzSurfaceFlinger(data, size); + + mTestableFlinger.setCreateBufferQueueFunction( + surfaceflinger::test::Factory::CreateBufferQueueFunction()); + mTestableFlinger.setCreateNativeWindowSurface( + surfaceflinger::test::Factory::CreateNativeWindowSurfaceFunction()); + + setInternalDisplayPrimaries(); + + mTestableFlinger.enableHalVirtualDisplays(mFdp.ConsumeBool()); + + mTestableFlinger.commitTransactionsLocked(mFdp.ConsumeIntegral<uint32_t>()); + + mTestableFlinger.notifyPowerBoost(mFdp.ConsumeIntegral<int32_t>()); + + setDisplayStateLocked(); + + setTransactionState(); + mTestableFlinger.flushTransactionQueues(); + + onTransact(data, size); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + android::fuzz::SurfaceFlingerFuzzer surfaceFlingerFuzzer(data, size); + surfaceFlingerFuzzer.process(data, size); + return 0; +} + +} // namespace android::fuzz diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h new file mode 100644 index 0000000000..ceb3e6410c --- /dev/null +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h @@ -0,0 +1,803 @@ +/* + * 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 <compositionengine/Display.h> +#include <compositionengine/LayerFECompositionState.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/CompositionEngine.h> +#include <compositionengine/impl/Display.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> +#include <gui/LayerDebugInfo.h> +#include <gui/ScreenCaptureResults.h> +#include <gui/SurfaceComposerClient.h> +#include <gui/mock/GraphicBufferProducer.h> +#include <ui/DisplayStatInfo.h> +#include <ui/DynamicDisplayInfo.h> + +#include "BufferQueueLayer.h" +#include "BufferStateLayer.h" +#include "ContainerLayer.h" +#include "DisplayDevice.h" +#include "DisplayHardware/ComposerHal.h" +#include "EffectLayer.h" +#include "FrameTimeline/FrameTimeline.h" +#include "FrameTracer/FrameTracer.h" +#include "Layer.h" +#include "NativeWindowSurface.h" +#include "Scheduler/EventThread.h" +#include "Scheduler/MessageQueue.h" +#include "Scheduler/RefreshRateConfigs.h" +#include "Scheduler/TimeKeeper.h" +#include "Scheduler/VSyncTracker.h" +#include "Scheduler/VsyncConfiguration.h" +#include "Scheduler/VsyncController.h" +#include "Scheduler/VsyncModulator.h" +#include "StartPropertySetThread.h" +#include "SurfaceFlinger.h" +#include "SurfaceFlingerDefaultFactory.h" +#include "SurfaceInterceptor.h" +#include "TimeStats/TimeStats.h" + +#include "renderengine/mock/RenderEngine.h" +#include "tests/unittests/mock/DisplayHardware/MockComposer.h" +#include "tests/unittests/mock/DisplayHardware/MockHWC2.h" +#include "tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h" +#include "tests/unittests/mock/MockEventThread.h" +#include "tests/unittests/mock/MockFrameTimeline.h" +#include "tests/unittests/mock/MockFrameTracer.h" +#include "tests/unittests/mock/MockNativeWindowSurface.h" +#include "tests/unittests/mock/MockSurfaceInterceptor.h" +#include "tests/unittests/mock/MockTimeStats.h" +#include "tests/unittests/mock/MockVSyncTracker.h" +#include "tests/unittests/mock/MockVsyncController.h" + +namespace android { +namespace Hwc2 { + +class Composer; + +namespace types = hardware::graphics::common; + +namespace V2_1 = hardware::graphics::composer::V2_1; +namespace V2_2 = hardware::graphics::composer::V2_2; +namespace V2_3 = hardware::graphics::composer::V2_3; +namespace V2_4 = hardware::graphics::composer::V2_4; + +using types::V1_0::ColorTransform; +using types::V1_0::Transform; +using types::V1_1::RenderIntent; +using types::V1_2::ColorMode; +using types::V1_2::Dataspace; +using types::V1_2::Hdr; +using types::V1_2::PixelFormat; + +using V2_1::Config; +using V2_1::Display; +using V2_1::Error; +using V2_1::Layer; +using V2_4::CommandReaderBase; +using V2_4::CommandWriterBase; +using V2_4::IComposer; +using V2_4::IComposerCallback; +using V2_4::IComposerClient; +using V2_4::VsyncPeriodChangeTimeline; +using V2_4::VsyncPeriodNanos; +using DisplayCapability = IComposerClient::DisplayCapability; +using PerFrameMetadata = IComposerClient::PerFrameMetadata; +using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey; +using PerFrameMetadataBlob = IComposerClient::PerFrameMetadataBlob; +}; // namespace Hwc2 + +static constexpr hal::HWDisplayId kHwDisplayId = 1000; + +static constexpr ui::Hdr kHdrTypes[] = {ui::Hdr::DOLBY_VISION, ui::Hdr::HDR10, ui::Hdr::HLG, + ui::Hdr::HDR10_PLUS}; + +static constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE, + ui::ColorMode::STANDARD_BT601_625, + ui::ColorMode::STANDARD_BT601_625_UNADJUSTED, + ui::ColorMode::STANDARD_BT601_525, + ui::ColorMode::STANDARD_BT601_525_UNADJUSTED, + ui::ColorMode::STANDARD_BT709, + ui::ColorMode::DCI_P3, + ui::ColorMode::SRGB, + ui::ColorMode::ADOBE_RGB, + ui::ColorMode::DISPLAY_P3, + ui::ColorMode::BT2020, + ui::ColorMode::BT2100_PQ, + ui::ColorMode::BT2100_HLG, + ui::ColorMode::DISPLAY_BT2020}; + +FloatRect getFuzzedFloatRect(FuzzedDataProvider *fdp) { + return FloatRect(fdp->ConsumeFloatingPoint<float>() /*left*/, + fdp->ConsumeFloatingPoint<float>() /*right*/, + fdp->ConsumeFloatingPoint<float>() /*top*/, + fdp->ConsumeFloatingPoint<float>() /*bottom*/); +} + +HdrMetadata getFuzzedHdrMetadata(FuzzedDataProvider *fdp) { + HdrMetadata hdrMetadata; + if (fdp->ConsumeBool()) { + hdrMetadata.cta8613.maxContentLightLevel = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.cta8613.maxFrameAverageLightLevel = fdp->ConsumeFloatingPoint<float>(); + + hdrMetadata.validTypes |= HdrMetadata::CTA861_3; + } else { + hdrMetadata.smpte2086.displayPrimaryRed.x = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.displayPrimaryRed.y = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.displayPrimaryGreen.x = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.displayPrimaryGreen.y = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.displayPrimaryBlue.x = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.displayPrimaryBlue.y = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.whitePoint.x = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.whitePoint.y = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.minLuminance = fdp->ConsumeFloatingPoint<float>(); + hdrMetadata.smpte2086.maxLuminance = fdp->ConsumeFloatingPoint<float>(); + + hdrMetadata.validTypes |= HdrMetadata::SMPTE2086; + } + return hdrMetadata; +} + +class EventThread; + +namespace hal = android::hardware::graphics::composer::hal; + +struct FakePhaseOffsets : scheduler::VsyncConfiguration { + static constexpr nsecs_t FAKE_PHASE_OFFSET_NS = 0; + static constexpr auto FAKE_DURATION_OFFSET_NS = std::chrono::nanoseconds(0); + + VsyncConfigSet getConfigsForRefreshRate(Fps) const override { return getCurrentConfigs(); } + + VsyncConfigSet getCurrentConfigs() const override { + return {{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, + FAKE_DURATION_OFFSET_NS}, + {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, + FAKE_DURATION_OFFSET_NS}, + {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, + FAKE_DURATION_OFFSET_NS}, + FAKE_DURATION_OFFSET_NS}; + } + + void reset() override {} + void setRefreshRateFps(Fps) override {} + void dump(std::string &) const override {} +}; +namespace scheduler { +class TestableScheduler : public Scheduler, private ICompositor { +public: + TestableScheduler(const std::shared_ptr<scheduler::RefreshRateConfigs> &refreshRateConfigs, + ISchedulerCallback &callback) + : TestableScheduler(std::make_unique<android::mock::VsyncController>(), + std::make_unique<android::mock::VSyncTracker>(), refreshRateConfigs, + callback) {} + + void scheduleFrame(){}; + void postMessage(sp<MessageHandler> &&){}; + + TestableScheduler(std::unique_ptr<VsyncController> controller, + std::unique_ptr<VSyncTracker> tracker, + std::shared_ptr<RefreshRateConfigs> configs, ISchedulerCallback &callback) + : Scheduler(*this, callback, Feature::kContentDetection) { + mVsyncSchedule.emplace(VsyncSchedule(std::move(tracker), nullptr, std::move(controller))); + setRefreshRateConfigs(std::move(configs)); + } + + ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) { + return Scheduler::createConnection(std::move(eventThread)); + } + + auto &mutablePrimaryHWVsyncEnabled() { return mPrimaryHWVsyncEnabled; } + auto &mutableHWVsyncAvailable() { return mHWVsyncAvailable; } + + auto &mutableLayerHistory() { return mLayerHistory; } + + auto refreshRateConfigs() { return holdRefreshRateConfigs(); } + + void replaceTouchTimer(int64_t millis) { + if (mTouchTimer) { + mTouchTimer.reset(); + } + mTouchTimer.emplace( + "Testable Touch timer", std::chrono::milliseconds(millis), + [this] { touchTimerCallback(TimerState::Reset); }, + [this] { touchTimerCallback(TimerState::Expired); }); + mTouchTimer->start(); + } + + bool isTouchActive() { + std::lock_guard<std::mutex> lock(mPolicyLock); + return mPolicy.touch == Scheduler::TouchState::Active; + } + + void dispatchCachedReportedMode() { + std::lock_guard<std::mutex> lock(mPolicyLock); + return Scheduler::dispatchCachedReportedMode(); + } + + void clearCachedReportedMode() { + std::lock_guard<std::mutex> lock(mPolicyLock); + mPolicy.cachedModeChangedParams.reset(); + } + + void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) { + return Scheduler::onNonPrimaryDisplayModeChanged(handle, mode); + } + +private: + // ICompositor overrides: + bool commit(nsecs_t, int64_t, nsecs_t) override { return false; } + void composite(nsecs_t) override {} + void sample() override {} +}; +}; // namespace scheduler + +namespace surfaceflinger::test { + +class Factory final : public surfaceflinger::Factory { +public: + ~Factory() = default; + + std::unique_ptr<HWComposer> createHWComposer(const std::string &) override { return nullptr; } + + std::unique_ptr<MessageQueue> createMessageQueue(ICompositor &compositor) { + return std::make_unique<android::impl::MessageQueue>(compositor); + } + + std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( + Fps /*currentRefreshRate*/) override { + return std::make_unique<FakePhaseOffsets>(); + } + + std::unique_ptr<scheduler::Scheduler> createScheduler( + const std::shared_ptr<scheduler::RefreshRateConfigs> &, + scheduler::ISchedulerCallback &) { + return nullptr; + } + + sp<SurfaceInterceptor> createSurfaceInterceptor() override { + return new android::impl::SurfaceInterceptor(); + } + + sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override { + return new StartPropertySetThread(timestampPropertyValue); + } + + sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs &creationArgs) override { + return new DisplayDevice(creationArgs); + } + + sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, + uint32_t layerCount, uint64_t usage, + std::string requestorName) override { + return new GraphicBuffer(width, height, format, layerCount, usage, requestorName); + } + + void createBufferQueue(sp<IGraphicBufferProducer> *outProducer, + sp<IGraphicBufferConsumer> *outConsumer, + bool consumerIsSurfaceFlinger) override { + if (!mCreateBufferQueue) { + BufferQueue::createBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger); + return; + } + mCreateBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger); + } + + sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer> &producer, + const sp<SurfaceFlinger> &flinger, + const wp<Layer> &layer) override { + return new MonitoredProducer(producer, flinger, layer); + } + + sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer> &consumer, + renderengine::RenderEngine &renderEngine, + uint32_t textureName, Layer *layer) override { + return new BufferLayerConsumer(consumer, renderEngine, textureName, layer); + } + + std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface( + const sp<IGraphicBufferProducer> &producer) override { + if (!mCreateNativeWindowSurface) return nullptr; + return mCreateNativeWindowSurface(producer); + } + + std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override { + return compositionengine::impl::createCompositionEngine(); + } + + sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs &) override { + return nullptr; + } + + sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs &) override { + return nullptr; + } + + sp<EffectLayer> createEffectLayer(const LayerCreationArgs &args) override { + return new EffectLayer(args); + } + + sp<ContainerLayer> createContainerLayer(const LayerCreationArgs &args) override { + return new ContainerLayer(args); + } + + std::unique_ptr<FrameTracer> createFrameTracer() override { + return std::make_unique<android::mock::FrameTracer>(); + } + + std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline( + std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid = 0) override { + return std::make_unique<android::mock::FrameTimeline>(timeStats, surfaceFlingerPid); + } + + using CreateBufferQueueFunction = + std::function<void(sp<IGraphicBufferProducer> * /* outProducer */, + sp<IGraphicBufferConsumer> * /* outConsumer */, + bool /* consumerIsSurfaceFlinger */)>; + CreateBufferQueueFunction mCreateBufferQueue; + + using CreateNativeWindowSurfaceFunction = + std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>( + const sp<IGraphicBufferProducer> &)>; + CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface; + + using CreateCompositionEngineFunction = + std::function<std::unique_ptr<compositionengine::CompositionEngine>()>; + CreateCompositionEngineFunction mCreateCompositionEngine; +}; + +} // namespace surfaceflinger::test + +// TODO(b/189053744) : Create a common test/mock library for surfaceflinger +class TestableSurfaceFlinger final : private scheduler::ISchedulerCallback { +public: + using HotplugEvent = SurfaceFlinger::HotplugEvent; + + SurfaceFlinger *flinger() { return mFlinger.get(); } + scheduler::TestableScheduler *scheduler() { return mScheduler; } + + // Allow reading display state without locking, as if called on the SF main thread. + auto onInitializeDisplays() NO_THREAD_SAFETY_ANALYSIS { + return mFlinger->onInitializeDisplays(); + } + + void scheduleComposite(FrameHint){}; + + void setGlobalShadowSettings(FuzzedDataProvider *fdp) { + const half4 ambientColor{fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>()}; + const half4 spotColor{fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>(), + fdp->ConsumeFloatingPoint<float>()}; + float lightPosY = fdp->ConsumeFloatingPoint<float>(); + float lightPosZ = fdp->ConsumeFloatingPoint<float>(); + float lightRadius = fdp->ConsumeFloatingPoint<float>(); + mFlinger->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, + lightRadius); + } + + void onPullAtom(FuzzedDataProvider *fdp) { + const int32_t atomId = fdp->ConsumeIntegral<uint8_t>(); + std::string pulledData = fdp->ConsumeRandomLengthString().c_str(); + bool success = fdp->ConsumeBool(); + mFlinger->onPullAtom(atomId, &pulledData, &success); + } + + void fuzzDumpsysAndDebug(FuzzedDataProvider *fdp) { + std::string result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->appendSfConfigString(result); + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->listLayersLocked(result); + + using DumpArgs = Vector<String16>; + DumpArgs dumpArgs; + dumpArgs.push_back(String16(fdp->ConsumeRandomLengthString().c_str())); + mFlinger->clearStatsLocked(dumpArgs, result); + + mFlinger->dumpTimeStats(dumpArgs, fdp->ConsumeBool(), result); + mFlinger->logFrameStats(); + + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->dumpFrameTimeline(dumpArgs, result); + + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->dumpStaticScreenStats(result); + + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->dumpFrameEventsLocked(result); + + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->dumpRawDisplayIdentificationData(dumpArgs, result); + + LayersProto layersProto = mFlinger->dumpDrawingStateProto(fdp->ConsumeIntegral<uint32_t>()); + mFlinger->dumpOffscreenLayersProto(layersProto); + LayersTraceProto layersTraceProto{}; + mFlinger->dumpDisplayProto(layersTraceProto); + + result = fdp->ConsumeRandomLengthString().c_str(); + mFlinger->dumpHwc(result); + + mFlinger->calculateColorMatrix(fdp->ConsumeFloatingPoint<float>()); + mFlinger->updateColorMatrixLocked(); + mFlinger->CheckTransactCodeCredentials(fdp->ConsumeIntegral<uint32_t>()); + + const CountDownLatch transactionCommittedSignal(fdp->ConsumeIntegral<uint32_t>()); + mFlinger->waitForSynchronousTransaction(transactionCommittedSignal); + mFlinger->signalSynchronousTransactions(fdp->ConsumeIntegral<uint32_t>()); + } + + void getCompositionPreference() { + ui::Dataspace outDataspace; + ui::PixelFormat outPixelFormat; + ui::Dataspace outWideColorGamutDataspace; + ui::PixelFormat outWideColorGamutPixelFormat; + mFlinger->getCompositionPreference(&outDataspace, &outPixelFormat, + &outWideColorGamutDataspace, + &outWideColorGamutPixelFormat); + } + + void overrideHdrTypes(sp<IBinder> &display, FuzzedDataProvider *fdp) { + std::vector<ui::Hdr> hdrTypes; + hdrTypes.push_back(fdp->PickValueInArray(kHdrTypes)); + mFlinger->overrideHdrTypes(display, hdrTypes); + } + + void getDisplayedContentSample(sp<IBinder> &display, FuzzedDataProvider *fdp) { + DisplayedFrameStats outDisplayedFrameStats; + mFlinger->getDisplayedContentSample(display, fdp->ConsumeIntegral<uint64_t>(), + fdp->ConsumeIntegral<uint64_t>(), + &outDisplayedFrameStats); + } + + void getDisplayStats(sp<IBinder> &display) { + android::DisplayStatInfo stats; + mFlinger->getDisplayStats(display, &stats); + } + + void getDisplayState(sp<IBinder> &display) { + ui::DisplayState displayState; + mFlinger->getDisplayState(display, &displayState); + } + + void getStaticDisplayInfo(sp<IBinder> &display) { + ui::StaticDisplayInfo staticDisplayInfo; + mFlinger->getStaticDisplayInfo(display, &staticDisplayInfo); + } + + void getDynamicDisplayInfo(sp<IBinder> &display) { + android::ui::DynamicDisplayInfo dynamicDisplayInfo; + mFlinger->getDynamicDisplayInfo(display, &dynamicDisplayInfo); + } + void getDisplayNativePrimaries(sp<IBinder> &display) { + android::ui::DisplayPrimaries displayPrimaries; + mFlinger->getDisplayNativePrimaries(display, displayPrimaries); + } + + void getDesiredDisplayModeSpecs(sp<IBinder> &display) { + ui::DisplayModeId outDefaultMode; + bool outAllowGroupSwitching; + float outPrimaryRefreshRateMin; + float outPrimaryRefreshRateMax; + float outAppRequestRefreshRateMin; + float outAppRequestRefreshRateMax; + mFlinger->getDesiredDisplayModeSpecs(display, &outDefaultMode, &outAllowGroupSwitching, + &outPrimaryRefreshRateMin, &outPrimaryRefreshRateMax, + &outAppRequestRefreshRateMin, + &outAppRequestRefreshRateMax); + } + + void setVsyncConfig(FuzzedDataProvider *fdp) { + const scheduler::VsyncModulator::VsyncConfig vsyncConfig{}; + mFlinger->setVsyncConfig(vsyncConfig, fdp->ConsumeIntegral<nsecs_t>()); + } + + void updateCompositorTiming(FuzzedDataProvider *fdp) { + std::shared_ptr<FenceTime> presentFenceTime = FenceTime::NO_FENCE; + mFlinger->updateCompositorTiming({}, fdp->ConsumeIntegral<nsecs_t>(), presentFenceTime); + } + + void getCompositorTiming() { + CompositorTiming compositorTiming; + mFlinger->getCompositorTiming(&compositorTiming); + } + + sp<IBinder> fuzzBoot(FuzzedDataProvider *fdp) { + mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(fdp->ConsumeBool()); + mFlinger->createConnection(); + + DisplayIdGenerator<HalVirtualDisplayId> kGenerator; + HalVirtualDisplayId halVirtualDisplayId = kGenerator.generateId().value(); + + ui::Size uiSize{fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()}; + ui::PixelFormat pixelFormat{}; + mFlinger->getHwComposer().allocateVirtualDisplay(halVirtualDisplayId, uiSize, &pixelFormat); + + PhysicalDisplayId physicalDisplayId = SurfaceComposerClient::getInternalDisplayId().value(); + mFlinger->getHwComposer().allocatePhysicalDisplay(kHwDisplayId, physicalDisplayId); + + sp<IBinder> display = + mFlinger->createDisplay(String8(fdp->ConsumeRandomLengthString().c_str()), + fdp->ConsumeBool()); + + onInitializeDisplays(); + mFlinger->getPhysicalDisplayToken(physicalDisplayId); + + mFlinger->mStartPropertySetThread = + mFlinger->getFactory().createStartPropertySetThread(fdp->ConsumeBool()); + + mFlinger->bootFinished(); + + return display; + } + + void fuzzSurfaceFlinger(const uint8_t *data, size_t size) { + FuzzedDataProvider mFdp(data, size); + + sp<IBinder> display = fuzzBoot(&mFdp); + + sp<IGraphicBufferProducer> bufferProducer = sp<mock::GraphicBufferProducer>::make(); + mFlinger->authenticateSurfaceTexture(bufferProducer.get()); + + mFlinger->createDisplayEventConnection(); + + getDisplayStats(display); + getDisplayState(display); + getStaticDisplayInfo(display); + getDynamicDisplayInfo(display); + getDisplayNativePrimaries(display); + + mFlinger->setAutoLowLatencyMode(display, mFdp.ConsumeBool()); + mFlinger->setGameContentType(display, mFdp.ConsumeBool()); + mFlinger->setPowerMode(display, mFdp.ConsumeIntegral<int>()); + mFlinger->clearAnimationFrameStats(); + + overrideHdrTypes(display, &mFdp); + + onPullAtom(&mFdp); + + mFlinger->injectVSync(mFdp.ConsumeIntegral<nsecs_t>()); + + getCompositionPreference(); + getDisplayedContentSample(display, &mFdp); + getDesiredDisplayModeSpecs(display); + + bool outSupport; + mFlinger->getDisplayBrightnessSupport(display, &outSupport); + + mFlinger->notifyPowerBoost(mFdp.ConsumeIntegral<int32_t>()); + + setGlobalShadowSettings(&mFdp); + + mFlinger->binderDied(display); + mFlinger->onFirstRef(); + + mFlinger->commitTransactions(); + mFlinger->updateInputFlinger(); + mFlinger->updateCursorAsync(); + + setVsyncConfig(&mFdp); + + mFlinger->flushTransactionQueues(0); + + mFlinger->setTransactionFlags(mFdp.ConsumeIntegral<uint32_t>()); + mFlinger->clearTransactionFlags(mFdp.ConsumeIntegral<uint32_t>()); + mFlinger->commitOffscreenLayers(); + + mFlinger->frameIsEarly(mFdp.ConsumeIntegral<nsecs_t>(), mFdp.ConsumeIntegral<int64_t>()); + mFlinger->computeLayerBounds(); + mFlinger->startBootAnim(); + + mFlinger->readPersistentProperties(); + + mFlinger->exceedsMaxRenderTargetSize(mFdp.ConsumeIntegral<uint32_t>(), + mFdp.ConsumeIntegral<uint32_t>()); + + mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mFdp.ConsumeIntegral<uid_t>()); + + mFlinger->postComposition(); + + getCompositorTiming(); + + updateCompositorTiming(&mFdp); + + mFlinger->setCompositorTimingSnapped({}, mFdp.ConsumeIntegral<nsecs_t>()); + mFlinger->postFrame(); + mFlinger->calculateExpectedPresentTime({}); + + mFlinger->enableHalVirtualDisplays(mFdp.ConsumeBool()); + + fuzzDumpsysAndDebug(&mFdp); + + mFlinger->destroyDisplay(display); + } + + void setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) { + mFlinger->mCompositionEngine->setRenderEngine(std::move(renderEngine)); + } + + void setupComposer(std::unique_ptr<Hwc2::Composer> composer) { + mFlinger->mCompositionEngine->setHwComposer( + std::make_unique<impl::HWComposer>(std::move(composer))); + } + + void setupTimeStats(const std::shared_ptr<TimeStats> &timeStats) { + mFlinger->mCompositionEngine->setTimeStats(timeStats); + } + + // The ISchedulerCallback argument can be nullptr for a no-op implementation. + void setupScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController, + std::unique_ptr<scheduler::VSyncTracker> vsyncTracker, + std::unique_ptr<EventThread> appEventThread, + std::unique_ptr<EventThread> sfEventThread, + scheduler::ISchedulerCallback *callback = nullptr, + bool hasMultipleModes = false) { + DisplayModes modes{DisplayMode::Builder(0) + .setId(DisplayModeId(0)) + .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0)) + .setVsyncPeriod(16'666'667) + .setGroup(0) + .build()}; + + if (hasMultipleModes) { + modes.emplace_back(DisplayMode::Builder(1) + .setId(DisplayModeId(1)) + .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0)) + .setVsyncPeriod(11'111'111) + .setGroup(0) + .build()); + } + + const auto currMode = DisplayModeId(0); + mRefreshRateConfigs = std::make_shared<scheduler::RefreshRateConfigs>(modes, currMode); + const auto currFps = mRefreshRateConfigs->getCurrentRefreshRate().getFps(); + mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(currFps); + mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make( + mFlinger->mVsyncConfiguration->getCurrentConfigs()); + mFlinger->mRefreshRateStats = + std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps, + /*powerMode=*/hal::PowerMode::OFF); + + mScheduler = new scheduler::TestableScheduler(std::move(vsyncController), + std::move(vsyncTracker), mRefreshRateConfigs, + *(callback ?: this)); + + mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread)); + mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread)); + resetScheduler(mScheduler); + } + + void resetScheduler(scheduler::Scheduler *scheduler) { mFlinger->mScheduler.reset(scheduler); } + + scheduler::TestableScheduler &mutableScheduler() const { return *mScheduler; } + + using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction; + void setCreateBufferQueueFunction(CreateBufferQueueFunction f) { + mFactory.mCreateBufferQueue = f; + } + + using CreateNativeWindowSurfaceFunction = + surfaceflinger::test::Factory::CreateNativeWindowSurfaceFunction; + void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) { + mFactory.mCreateNativeWindowSurface = f; + } + + void setInternalDisplayPrimaries(const ui::DisplayPrimaries &primaries) { + memcpy(&mFlinger->mInternalDisplayPrimaries, &primaries, sizeof(ui::DisplayPrimaries)); + } + + static auto &mutableLayerDrawingState(const sp<Layer> &layer) { return layer->mDrawingState; } + + auto &mutableStateLock() { return mFlinger->mStateLock; } + + static auto findOutputLayerForDisplay(const sp<Layer> &layer, + const sp<const DisplayDevice> &display) { + return layer->findOutputLayerForDisplay(display.get()); + } + + /* ------------------------------------------------------------------------ + * Forwarding for functions being tested + */ + + void enableHalVirtualDisplays(bool enable) { mFlinger->enableHalVirtualDisplays(enable); } + + auto commitTransactionsLocked(uint32_t transactionFlags) { + Mutex::Autolock lock(mFlinger->mStateLock); + return mFlinger->commitTransactionsLocked(transactionFlags); + } + + auto setDisplayStateLocked(const DisplayState &s) { + Mutex::Autolock lock(mFlinger->mStateLock); + return mFlinger->setDisplayStateLocked(s); + } + + auto notifyPowerBoost(int32_t boostId) { return mFlinger->notifyPowerBoost(boostId); } + + // Allow reading display state without locking, as if called on the SF main thread. + auto setPowerModeInternal(const sp<DisplayDevice> &display, + hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS { + return mFlinger->setPowerModeInternal(display, mode); + } + + auto onMessageReceived(int32_t /*what*/) { return 0; } + + auto &getTransactionQueue() { return mFlinger->mTransactionQueue; } + auto &getPendingTransactionQueue() { return mFlinger->mPendingTransactionQueues; } + + auto setTransactionState( + const FrameTimelineInfo &frameTimelineInfo, const Vector<ComposerState> &states, + const Vector<DisplayState> &displays, uint32_t flags, const sp<IBinder> &applyToken, + const InputWindowCommands &inputWindowCommands, int64_t desiredPresentTime, + bool isAutoTimestamp, const client_cache_t &uncacheBuffer, bool hasListenerCallbacks, + std::vector<ListenerCallbacks> &listenerCallbacks, uint64_t transactionId) { + return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken, + inputWindowCommands, desiredPresentTime, + isAutoTimestamp, uncacheBuffer, hasListenerCallbacks, + listenerCallbacks, transactionId); + } + + auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(0); }; + + auto onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { + return mFlinger->onTransact(code, data, reply, flags); + } + + auto getGPUContextPriority() { return mFlinger->getGPUContextPriority(); } + + auto calculateMaxAcquiredBufferCount(Fps refreshRate, + std::chrono::nanoseconds presentLatency) const { + return SurfaceFlinger::calculateMaxAcquiredBufferCount(refreshRate, presentLatency); + } + + /* Read-write access to private data to set up preconditions and assert + * post-conditions. + */ + + auto &mutableCurrentState() { return mFlinger->mCurrentState; } + auto &mutableDisplays() { return mFlinger->mDisplays; } + auto &mutableDrawingState() { return mFlinger->mDrawingState; } + auto &mutableInterceptor() { return mFlinger->mInterceptor; } + + auto fromHandle(const sp<IBinder> &handle) { return mFlinger->fromHandle(handle); } + + ~TestableSurfaceFlinger() { + mutableDisplays().clear(); + mutableCurrentState().displays.clear(); + mutableDrawingState().displays.clear(); + mutableInterceptor().clear(); + mFlinger->mScheduler.reset(); + mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>()); + mFlinger->mCompositionEngine->setRenderEngine( + std::unique_ptr<renderengine::RenderEngine>()); + } + +private: + void scheduleRefresh(FrameHint) {} + void setVsyncEnabled(bool) override {} + void changeRefreshRate(const RefreshRate &, DisplayModeEvent) override {} + void kernelTimerChanged(bool) override {} + void triggerOnFrameRateOverridesChanged() {} + + surfaceflinger::test::Factory mFactory; + sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization); + scheduler::TestableScheduler *mScheduler = nullptr; + std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs; +}; +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index bba880ec90..d649c62fcb 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -21,6 +21,24 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +filegroup { + name: "libsurfaceflinger_mock_sources", + srcs: [ + "mock/DisplayHardware/MockComposer.cpp", + "mock/DisplayHardware/MockHWC2.cpp", + "mock/DisplayHardware/MockPowerAdvisor.cpp", + "mock/MockEventThread.cpp", + "mock/MockFrameTimeline.cpp", + "mock/MockFrameTracer.cpp", + "mock/MockNativeWindowSurface.cpp", + "mock/MockSurfaceInterceptor.cpp", + "mock/MockTimeStats.cpp", + "mock/MockVsyncController.cpp", + "mock/MockVSyncTracker.cpp", + "mock/system/window/MockNativeWindow.cpp", + ], +} + cc_test { name: "libsurfaceflinger_unittest", defaults: [ @@ -45,6 +63,7 @@ cc_test { address: true, }, srcs: [ + ":libsurfaceflinger_mock_sources", ":libsurfaceflinger_sources", "libsurfaceflinger_unittest_main.cpp", "CachingTest.cpp", @@ -104,18 +123,6 @@ cc_test { "VSyncPredictorTest.cpp", "VSyncReactorTest.cpp", "VsyncConfigurationTest.cpp", - "mock/DisplayHardware/MockComposer.cpp", - "mock/DisplayHardware/MockHWC2.cpp", - "mock/DisplayHardware/MockPowerAdvisor.cpp", - "mock/MockEventThread.cpp", - "mock/MockFrameTimeline.cpp", - "mock/MockFrameTracer.cpp", - "mock/MockNativeWindowSurface.cpp", - "mock/MockSurfaceInterceptor.cpp", - "mock/MockTimeStats.cpp", - "mock/MockVsyncController.cpp", - "mock/MockVSyncTracker.cpp", - "mock/system/window/MockNativeWindow.cpp", ], static_libs: [ "android.hardware.common-V2-ndk", |